PDA

View Full Version : QStackWidget example



indianinside
26th June 2012, 19:03
I am trying to build a desktop app.

I just need to know how to put widgets onto QStackWidget and display one by one ? just a simple example would be good enough. and if i load a file and then generate pages after parsing it, how do I add the pages dynamically to the QStackWidget ? in the example in the documentation they show creating pages and then inserting them onto QStackWidget.

So I need some help ..some inputs would be helpful..Thanks

amleto
26th June 2012, 22:30
I dont get what is so difficult/different.



QWidget *firstPageWidget = new QWidget;
QWidget *secondPageWidget = new QWidget;
QWidget *thirdPageWidget = new QWidget;

QStackedWidget *stackedWidget = new QStackedWidget;
stackedWidget->addWidget(firstPageWidget);
stackedWidget->addWidget(secondPageWidget);
stackedWidget->addWidget(thirdPageWidget);


all you have to do is read a file, generate the widgets, add them to the stackedwidget.

indianinside
27th June 2012, 15:57
Yes, i have done this .. But I don't know how to generate the widgets on the fly ? i.e every page should have a widget. so in what I have done. I have put the things into stackwidget before, i.e i create page widgets and then put them into the stackwidget.

but i need to know how to generate widgets on the fly when i read the file and create so many widgets as many pages I have.

yeye_olive
27th June 2012, 16:05
You realize C++ has loop constructs, right?

indianinside
27th June 2012, 18:35
you are not understanding..its not about how to code.. I know that ! and its no use being sarcastic.
its about how it is to be done..
I haven't got the clear idea of flow.. if I generate widgets, I give the name of the widget for each page like page1widget ...and so on etc..

But how do I do that on the fly ? i.e as soon as I read the file, I should be able to generate the widgets. that was what I was looking for..

anyway thanks for the "loop constructs" !

amleto
27th June 2012, 18:43
"i.e as soon as I read the file, I should be able to generate the widgets. that was what I was looking for.."

1 - Read file.
2 - Make widgets.


Where are you stuck?

d_stranz
28th June 2012, 00:54
I just need to know how to put widgets onto QStackWidget and display one by one ? just a simple example would be good enough. and if i load a file and then generate pages after parsing it, how do I add the pages dynamically to the QStackWidget ? in the example in the documentation they show creating pages and then inserting them onto QStackWidget.

So I need some help ..some inputs would be helpful..Thanks

Don't start a new thread asking the same question you asked in a previous thread. It isn't polite, especially when people are still answering the questions in the first posting.

Although I strongly think that your approach of creating a widget for every page in your document is the wrong way to do what you are trying to do, if you want to persist in going down this road by driving backwards, here's what you need to do:

- In the constructor for your main display view (call it the "PageView" class), you create a QStackedWidget. Nothing more. Do not add pages to it, nothing. Hold it in a member variable, call it "stackedWidget".

- PageView class needs a member variable QVector< QWidget * > that holds the widget pointers for each page. Call it "pageImages"

- PageView needs a slot, something that tells it the document you want to display has changed. Call it "onDocumentChanged". Maybe it also passes a pointer to some kind of Document object, that can tell the PageView how many pages there are in the document.

- In this slot, the simplest, most brute force way to do things is to 1) remove all of the child widgets from the QStackedWidget (if any) and destroy them, and 2) add a new child widget to the stack for each page in the Document and put the image in it. The pseudocode to do this would look something like this:



void PageView::onDocumentChanged( Document * pDoc )
{
// Delete all of the old page widgets first
foreach( QWidget * pWidget, pageImages )
{
stackedWidget->removeWidget( pWidget ); // only removes the widget, doesn't delete it
pWidget->deleteLater(); // but this will
}

// and empty the vector of the now deleted pointers
pageImages.clear();

// now create new page widgets for every page in the document
if ( pDoc )
{
int nPages = pDoc->pageCount();
for ( int nPage = 0; nPage < nPages; ++nPage )
{
PageImageWidget * pPageImage = new PageImageWidget(); // or whatever class it is you use to display the page images
pPageImage->setImage( pDoc->generatePageImage( nPage ) ); // making this up - you have to write this
stackedWidget->addWidget( pPageImage ); // add the new widget to the stack
pageImages.push_back( pPageImage ); // and remember it in the vector
}
}

stackedWidget->setCurrentIndex( 0 ); // display the first page
}


You could rely on the QObject::children() method to store and return the list of child widgets in the stack, but I find it simpler to maintain a separate list in the QVector. That way, I can go directly to a specific child widget without having to retrieve the whle list first from the stack.

indianinside
28th June 2012, 19:40
First of all sorry for sub-topic ing and posting it again..Will keep that in mind..

Thanks. Will check on this and try to implement this way.. will try both the ways with stackwidget and without.. but as said before, making widgets for each page seems not a good option, so will try the approach but without stackwidget.

thanks a lot.

I do believe what you said about creating individual widgets for each page is not a right option, so what would you suggest instead of that ?
make use of signals and slots and do something like this ?

- thumbnails (qlistwidget)
- content (qgraphicsview)

keep signals and slots to interact and paint each page when a page is requested. and keep few thumbnails and content in cache, say maybe 10 of them ?

would this be a good idea instead of the non-efficient stackwidget idea..

d_stranz
28th June 2012, 22:55
- thumbnails (qlistwidget)
- content (qgraphicsview)


QListWidget might be suitable, but if you really want to emulate Acrobat Reader behavior, I would use a QTableWidget instead, so if the user expanded the thumbnail sidebar to make it wider, you could reorganize the thumbnails into two or more columns. QListWidget would give you only one column.

You could use QGraphicsView for the content display with the page implemented as a QGraphicsPixmapItem. It would give the ability to zoom the image easily, but I am not sure the appearance would be very appealing. If you use a QTextEdit instead, you could easily scale the page simply by changing the font size, and get a very accurate representation (as opposed to a pixmap, which could eventually be zoomed to the point where it becomes pixelated - whereas fonts won't).

But since you are already parsing the document content when you read it in, you know what's in it. Why throw that away by converting the text to a picture of text? If you keep it as text and display it in a QTextEdit, you give the user (and yourself) the ability to search for and highlight phrases, copy text for pasting elsewhere, and other text-related operations. In particular, selecting text is pretty hard to do when the user interacts with an image - you have to go backwards from mouse coordinates in pixels to the mapping of text to those same pixels in the image. QTextEdit gives that to you for free - you just have to listen for the right signals.

For thumbnails, you need as many as you have visible cells in the thumbnail viewer. When the table scrolls, you shift the images from cell to cell as appropriate, generating new pixmaps when needed and throwing away old ones that are no longer visible. Alternatively, you could keep an array of pixmap pointers, one for every page in the document, generate them as needed (i.e. when the pages become visible in the thumbnail browser), and never throw them away until the document is closed. Since the thumbnails are pretty small, you could probably keep the entire document's worth without memory issues.

indianinside
28th June 2012, 23:09
thats nice..will use those widgets suggested.
but i wouldn't use Qtextwidget as my content is binary data not in text format. it comes in different formats something like unipen etc..so basically i will be storing the data in QLists etc.. so in this case I wouldn't be able to use Qtextwidget right ?

so I have to use Qgraphicspixmapitem or similar and as Qgraphicsview and Qgraphicsscene already have option of makiing things zoom and editable, I could make use of them ? am i right ?

d_stranz
28th June 2012, 23:31
In your original post you said:


I want to do a multi-file format reader..I have the parsers done for few of the file formats that I need. But I want to make a GUI like Adobe Acrobat Reader.
i.e show thumbnails of the files on the left sidebar and content on the right.

So what do you mean when you say you have "parsers"? It is irrelevant whether the files you read are binary. What are you converting their content to when you "parse" them?

indianinside
29th June 2012, 07:31
I am converting to simple xy coord and storing in a qlist

d_stranz
29th June 2012, 16:17
I am converting to simple xy coord and storing in a qlist

What are you converting to "simple xy coord"? The text in the PDF or other format file? How do you convert text into x-y coordinates?

Give me an example: If the file contained the text "I want to do a multi-file format reader", how do you turn that string into an x-y pair?

indianinside
3rd July 2012, 19:27
the data which is in the files itself is a x-y pair , i don't make it, i only read the data from files and and store it.