PDA

View Full Version : Qt GUI interface like Adobe Acrobat Reader



indianinside
21st June 2012, 16:18
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. And also it should take care of multiple pages in a document. and usual functionalities like going back and forward to pages etc..

I don't want to use the Qt Design as it dumps all the stuff in one huge file. I need to make separate files for each part so that I can make modifications additions easily.

So the problem is I don't know how to make the left sidebar fill up with images(thumbnails) and when clicked it should show up the respective content painted on the right. And I am using QGraphicsView framework so that my content are editable/draggable later. So something using qgraphicsview would be helpful.
Could somebody give a small demo of what I need or atleast bits and pieces of what I am looking for. Right now my UI looks like a simple reader with menu on top and the central widget shows the content when a file is loaded through the file menu.

So I need some help on the UI and also how to distribute and store things of UI in different classes and what has to be stored in what class and how the interaction takes place.
Its not that I am asking for spoon feeding, but after several tries of failed attempts to get the kind of UI and functionality I planned to post it on this forum.
any help would be appreciated.

amleto
21st June 2012, 16:49
one thing at a time. You want a thumbnail viewer. do you know how to make a single thumbnail? is your sidebar also using graphicsview?

indianinside
21st June 2012, 16:59
thanks for the reply.

yeh something like a thumbnail viewer, as this is not like an image viewer. I had tried to make single thumbnail using QImage scale function but couldnt make that work. Yes, the sidebar is a graphicsview as of now but I can make it into a QWdiget too, as it has no extra functionality other than clickable thumbnails on the left sidebar.

amleto
21st June 2012, 17:38
show what you have for thumbnail viewer in code and we can go on from there.

indianinside
21st June 2012, 18:05
oh no I have not implemented the viewer, I know only how to make thumbnails like this.. I wouldn't ask this help if I knew how to make the thumbnail viewer..

QImage result = img.scaled(800, 600).scaled(200, 150, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);

amleto
21st June 2012, 19:05
well, you're going to have to make a start by yourself and show some code. You say you have a graphics view sidebar. You'll probably want to put these in your scene/view http://qt-project.org/doc/qt-5.0/qgraphicspixmapitem.html

Why don't you try that and post some code if you get stuck.

ChrisW67
22nd June 2012, 00:15
I don't want to use the Qt Design as it dumps all the stuff in one huge file. I need to make separate files for each part so that I can make modifications additions easily.
Designer does not enforce a monolithic UI design on you. You can design widgets independently and aggregate them into a the main UI using the Promotion feature, or construct the main UI by hand and aggregate the widget that way.

indianinside
22nd June 2012, 11:21
Right now I have tried this (small snippet below) where I get a reduced image of a given image. I need idea on how to make the UI (the thumbnail viewer being just part of the whole UI) which I have mentioned before. Not code, I need ideas or what particular classes to use and why ? Any help ?



QGraphicsScene scene;
QgraphicsView view(&scene);

QImage img1("1.png");
QImage img2(img1.scaled(200, 150, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
QGraphicsPixmapItem item = scene.addPixmap(QPixmap::fromImage(img2));
view.show()


Added after 10 minutes:

One more thing I tried is using QLabel and adding images to a QHBoxLayout. but the thing is I need to make that thumbnail generation automatic from my content file, how is that possible.. ideas are fine..
My content part is a QGraphicsView and my left sidebar is a QFrame. So what help will it be if I change my sidebar to QGraphicsView or will QFrame is fine enough ?

amleto
22nd June 2012, 12:36
One more thing I tried is using QLabel and adding images to a QHBoxLayout. but the thing is I need to make that thumbnail generation automatic from my content file, how is that possible.. ideas are fine..

read file
make thumbnails

:confused:



if you are using graphics view/scene for thumbnail, then just use another one for the 'main' viewer. I'm not sure why you are so stuck on widget class choice.

indianinside
22nd June 2012, 12:41
ok will do that. Thanks

amleto
22nd June 2012, 14:28
Perhaps you are feeling a bit paralysed/daunted by the number of things that need to be done (general size of your app)?

My advice is identify separate components and then build & test them individually.

indianinside
25th June 2012, 14:59
yes you are right. its basically it should be similar to adobe acrobat interface with diff file type reading capabilities.

I am not able to realize when it comes to generalizing the app. individual app works fine for one type of file.
And UI interactions are one thing I am not able to make out. like If I have multiple pages.

say I have a struct and class like this.

struct p
{
QList<class Y> yitems;
int no;
}

class X
{
QList<p> pitems;
}

so when I have all my data into that struct p. and I know how many pitems are there, i.e no of pages. so how do I paint and display one below the other ?
right now all the data or pages, overwrite on a single page itself. Should I put each page data onto one widget each and then put all of them onto a QStackedWidget ? how does things work in adobe acrobat reader ? I am not able to realize that part of display. any comments ?

indianinside
26th June 2012, 15:04
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

d_stranz
27th June 2012, 23:18
I don't think you want to use QStackWidget for this. What if your document has 1000 pages? Do you intend to create a widget stack with 1000 widgets in it?

Somehow you seem to be hung up on the idea that there needs to be some 1 to 1 to 1 correspondence between the document pages, the thumbnails, and the individual page views. That is completely unnecessary. At most (if you want something that looks like Acrobat Reader) you need a widget that will display two pages side-by side. (And this side-by-side display is just two identical one-page displays with different content).

So, think about what happens in Acrobat Reader when you click a thumbnail (or click the page navigation arrows or manually enter a page number on the toolbar): Reader displays the page at the selected page index or the two pages at index and index + 1.

What do you need to do in your app to emulate this behavior? Here's how I would start out doing it:

- Obviously, you need to parse and format the input file into the in memory representations of each page. These probably shouldn't be images - that is hugely wasteful of memory resources. It should probably be rich text documents instead, which maintain the text characters rather than turn everything into bitmaps which are mostly white space. Rich text supports a large subset of HTML, including images and tables, so you can represent those parts of your documents as well.

- Next, you need to create thumbnails for the page index display. You don't need 1000 thumbnails, you need as many as will fit on the thumbnail page at one time. You then create the 10 or so thumbnails using the current index to the starting page (generally page zero to start), load them into the thumbnail images, and tell the vertical scrollbar how to increment itself based on the document size and number of visible thumbnails.

- Then you display the first (or first two) pages. You can choose to either render the rich text to an image and display that, or you can use the QTextEdit widget (with editing disabled) to display the page for you.

Your viewer pane (where the page is displayed) needs a slot ("onPageChanged") that receives a QTextDocument pointer that points to the page to be displayed. The toolbar controls and the thumbnail viewer need signals that emit a "currentIndexChanged" with an index. Your application's "document" (or whatever it is that holds the document read from disk) need a slot connected to these the "currentIndexChanged" signals, creates the QTextDocument for the current page, then emits a "pageChanged" signal with that pointer.

If you want to make the viewer side more general (able to display any number of pages, not just one or two), you could give it more control instead of just listening for page changes. For example, you could implement another set of signals and slots, where the viewer asks for pages, one after another, and also change the "pageChanged" signal described above to be a "firstPageChanged" signal that simply passes the index of the first page to be displayed. The viewer then emits a "gimmeTheTextDocumentForThisIndex( long index, QTextDocument * & doc)" signal for each page it needs to display. The listener (in this case the document / data model replies by filling the pointer reference with a formatted page or with a NULL if the end of the document has been reached.

So, while I might use a graphics view for the thumbnail browser, I certainly wouldn't use graphics view for the page display. I'd use QTextEdit, set to read only. I would probably start out by using a QTableWidget for the thumbnail browser instead, unless there are interactions with the thumbnails that just aren't possible in a table format. I can't think of any, and the table will take care of all the display and navigation issues for you automatically.

indianinside
28th June 2012, 18:32
Thanks. But I cant use textdocument stuff, as my content is not text, its binary data.. but the idea seems fine.. will try to implement this. Thanks for the steps and suggestions