tags:

views:

269

answers:

2

I have an application with the following UI forms deriving from QMainWindow

  • LoginWindow
  • TasksWindow
  • DetailsWindow

I'm supposed to login into the application in the LoginWindow where I will move to the TasksWindow. In the TasksWindow, I will choose an item from a combo box, and then I should move to the DetailsWindow and populate data related to that item. On the DetailsWindow, I will have a menu action to return me back to the TasksWindow.

Currently, what I have in mind (and what I've tried) is this. In the main.cpp:

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    LoginWindow loginWindow;
    loginWindow.showMaximized();

    return app.exec();
}

And in the LoginWindow push button:

void LoginWindow::on_loginButton_clicked()
{
        this->hide(); // hide the login window
        TasksWindow tasksWindow;
        tasksWindow.showMaximized();
}

is there a better way to do this? It is becoming unmanageable as now I have to include a reference to each window class that I'm supposed to go to, possibly creating circular references!

Note that I'm doing this and compiling the application to be a Qt Symbian application.

What is the best way to switch between application windows? I thought about using a QStackedWidget before, and actually tried it, but the problem then is that I would have to write all the code for handling the different events in the same file and also, the action menus are different across the windows.

Help! :)

A: 

It might be besides the point/question, but I would use modal dialogs for the login and details windows.

Morten Fjeldstad
I'm developing on Symbian, does it make a difference?
sabbour
+3  A: 

My suggestion is to use State Machine to manager all your status. It's fairly easy to extend also.

  1. Read the State Machine Framework documents in Qt Help.
  2. After you have some basic knowledge on Qt state machine framework, you may understand the approach below.

a.) Define necessary state, e.g. Guest, Logged In, Logged Out. You may have 3 dialogs (I defined an additional logged out dialog here) for each state, connect the state entered signal to dialog show slot, and connect state exited signal to dialog hide slot. In this way you don't need to worry about when to show/hide a dialog, just focus on the transition of states.

b). Define signals for dialogs, for example, signal "loggedIn" for loginWindow, signal "loggedOut" for TasksWindow, add a transition trigged by signal "loggedIn" from state Guest to Logged in.

c). So the initial state of the state machine is "guest", when this state entered, your loginWindow shows up. After log in information has been verfied, a "loggedIn" signal emitted, and the state of the machine will change from "guest" to "Logged In", so the loginWindow will be hide when "Guest" state exited, and your TasksWindow will show up when "Logged In" state entered.

d). You may end the session by clicking "log out" in your TasksWindow, also what you need to do is to define trisitions for states change.

e). A trick here: You can define a final state and connect the "finished" or "stopped" signal of the state machine to your application "quit" slot. Then after you have done all the things, the application will be closed automatically by state machine.

Easy to maintence and extend, and the logic is very clear by using state machine.

Mason Chang
I think the state machine approach is very good. One thing that I can't wrap my mind about it is where will the QStateMachine and QState objects be stored?Will they be stored in the main.cpp?How will the rest of the application be able to interact with them?Where will the transitions be defined?
sabbour
Yes you can try to store QStateMachine in your main.cpp. I didn't try this before, but it should work. After you added a new created QState object to QStateMachine, the StateMachine will take the ownership of QState object. QState object also takes ownership of transitions. To interact with the rest of the Application, you can define some signals and slots, connect them with states. Or, if the global state machine is too complicated, you define some local one, e.g. in your TasksWindow.
Mason Chang
I have ever made a simple wizard style application to test this approach. I defined all the dialogs, states, transitions in one place, and let the state machnie drive the wizard.
Mason Chang
Do you have sample code for this wizard? :)
sabbour
sure, I'll send my sample code to your gmail(got it from your blog).
Mason Chang