PDA

View Full Version : What's the best way to implement a MainWindow



darkadept
5th February 2007, 16:18
I've been struggling with figuring out what the best way to implement a Qt MainWindow program is that is more complex then what most examples show.

Let's say I would be trying to create a simple customer database. Examples would suggest to create a QMainWindow that contains all the QAction's, QToolBar's, and QMenu's and then the "form" widget set as the central widget.

Easy enough, but what if I want show a different "form". Let's say I'm also tracking the customer's investment information. Let's also add in a "form" that let's me browse/search through all the customers.

So I would have 3 "forms":

browse/search form
customer view/edit form
customer's investment view/edit form


I can think of a few different ways to implement this.

First, you could use the QMainWindow's central widget to just be the browse/search form and then pop-up new QWidget windows when the user wants to access the other "forms". This approach seems very dated and ugly to me.

Second, you could use a QTabWidget or QStackedWidget to make everything happen in the central widget portion of the QMainWindow. I really like this approach but run into problems with the action's, menu's, and toolbar's. If I include all the code for each action in the QMainWindow I end up having huge amounts of unrelated code.

Maybe I'm approaching this entirely wrong so that is why I ask for help.

To better illustrate what I'm thinking about, take a look at the Kontact program for KDE. When you click on an item in the sidebar it jumps to different "forms" or sections in the program, each with it's own menu's toolbars, etc. So to make a long story short, how do I emulate this functionality "properly" in Qt. ;)

wysota
5th February 2007, 16:29
Second, you could use a QTabWidget or QStackedWidget to make everything happen in the central widget portion of the QMainWindow.
I'd go for that one.

If I include all the code for each action in the QMainWindow I end up having huge amounts of unrelated code.
It depends where you place the code. You can code each "view" as a separate class and embed all action code related to that form in the class. Then you can expose actions from the class in the public API with methods like:

class MyWidget : public QWidget {
//...
QAction *openFileAction(){ return _openFileAction; } // not very safe, but works
//...
};

Finally you add the widget to the stack widget and add actions to toolbars and menus. You can even do the last part automatically if you implement some introspection mechanism.



To better illustrate what I'm thinking about, take a look at the Kontact program for KDE. When you click on an item in the sidebar it jumps to different "forms" or sections in the program, each with it's own menu's toolbars, etc. So to make a long story short, how do I emulate this functionality "properly" in Qt. ;)
Simply show or hide particular toolbars or actions.

darkadept
5th February 2007, 16:55
Ok so I essentially make view widgets and have the QMainWindow manage all the switching between views?

Can a view widget create the toolbar and menu and then pass that back to the QMainWindow or are there ownership problems with that?

Also, on a somewhat related note, if I use a stacked widget, create my "form" view widgets and dump them into the stacked widget, the minimum dimensions (width+height) of the stacked widget is always that of the largest widget in the stack, regardless of visibility. Is there any way around this?

Thanks for the help btw.

wysota
5th February 2007, 17:25
Ok so I essentially make view widgets and have the QMainWindow manage all the switching between views?
Yes, something like that.


Can a view widget create the toolbar and menu and then pass that back to the QMainWindow or are there ownership problems with that?
There shouldn't be any problems. QMainWindow has a addToolBar() method which you can use.


Also, on a somewhat related note, if I use a stacked widget, create my "form" view widgets and dump them into the stacked widget, the minimum dimensions (width+height) of the stacked widget is always that of the largest widget in the stack, regardless of visibility. Is there any way around this?

Yes, but it depends what behaviour you desire. You can always hide() some widget which will make the layout ignore it. If you then set a constraint on the top level window, it should adjust to the current page. You can see the Expanding Dialog (http://wiki.qtcentre.org/index.php?title=Expanding_Dialog) example in the wiki.

darkadept
5th February 2007, 17:41
Ok i'm going to test all this out and see if I can put it all together.

Thanks so much for the help.

<offtopic>(why oh why could Trolltech not have invented QDataWidgetMapper a few months earlier... it would have saved me SOO much time. hehhehehe.)</offtopic>

wysota
5th February 2007, 17:46
(why oh why could Trolltech not have invented QDataWidgetMapper a few months earlier... it would have saved me SOO much time. hehhehehe.)

I thought about something simmilar to QDataWidgetMapper some time earlier but didn't have time to implement it myself and then the Trolls beat me to it :)