PDA

View Full Version : How to write a processevents loop until mainwindow become visible ?



tonnot
7th December 2011, 19:13
I need to write a loop which mission is to loop until the mainwindow was visible.
Now I have :


do
{QApplication::processEvents(QEventLoop::AllEvents );}
while (MY_qtutil().w_tell_me_the_mainwindow()->isVisible()==false);

MY_qtutil().w_tell_me_the_mainwindow() returns the Qmainwindow from any part of my app (it is verified)

But allways I have visible == false....
What's happen ? processEvents does not let to the mainwindow visualization process was executed ?

I need to do this not from the mainwindow (That is I cant use the showevent method), but at custom setup for custom widgets.

Thanks.

d_stranz
7th December 2011, 19:36
You could implement a showEvent handler for your main window, and in that handler, emit a signal: "mainWindowVisible()". You can connect to this signal somewhere else in your code that constructs the custom widgets.

You don't need your processEvents loop at all.

tonnot
7th December 2011, 19:46
Yes, I know this way.
But I want to make my custom widget showevent independent.
In other words, how can I do to do a effective loop until the mainwindow was visible ?
Thanks for your time.

d_stranz
7th December 2011, 19:57
You did not say where you put your processEvents loop, so it is impossible to give any advice about why it doesn't work.

But once again, you keep trying to defeat Qt. The usual Qt way to know when something has occurred is to either implement an event handler (in the widget itself) or to have the widget send a signal that can be connected to something else that needs to know. If you have to implement a processEvents loop to continuously watch for some change, then you really aren't letting Qt do what it does best. Let Qt tell you when the window has become visible, don't keep asking and asking and asking in your loop. If you have a method to retrieve the main window pointer from anywhere, then you also have the ability to connect to a main window signal from anywhere.

tonnot
7th December 2011, 20:13
The processEvents loop which I want to write is located at a custom setup function inside my custom widget.

I have at any place (It can be a designer form, another widget, created by code, etc.)

My_custom_widget = new Custom_widget(this);
Inside it (my custom constructor), I need to setup some properties that depends on the mainwindow was visible. I need to access to some properties and explore the widgets contained, etc... I need to do these things after the mainwindow was visible and before my custom widged was visible.

And I dont want to depend on write emit signal for every widget where I' m going to use this custom widgets. This is the reason because I need to write this loop. (Imagine I give this custom widget to some friend and I have to tell him 'Hey, remember to create I_am_visible signal for every widget where you plan to use the custom widget ... ).

Thanks again d_stranz

d_stranz
7th December 2011, 20:23
OK, if you insist that this design is the only way to implement what you want, I don't know the answer to your question. Sorry.

tonnot
7th December 2011, 20:30
Thanks and excuse me If I'm persistent....
The main question I have is 'processevents all events does not work to let the mainwindow was showed ?

marcvanriet
7th December 2011, 21:07
Re-implement the showEvent of your custom widget.
According to the documentation there is an internal event that is generated just before your widget becomes visible.
I think that at that time the mainwindow or any other widget containing your custom widget is already visible, so you can start exploring their properties.

Regards,
Marc

d_stranz
7th December 2011, 21:25
The main question I have is 'processevents all events does not work to let the mainwindow was showed ?

It is impossible to answer your question without more details. When is this loop running? After the main window is created but before it is shown? After it is shown? Before the main app event loop is even running? Is the main window actually visible when you are inside this loop? Are you certain that the QWidget pointer that is being returned by your MY_qtutil().w_tell_me_the_mainwindow() method *really is* the main window and not some child or frame? Do you even know if the loop is executing? (Did you set a breakpoint inside it with the debugger?)

Simply posting a small piece of code and asking "why doesn't this work?" doesn't give us many clues to help you.

tonnot
7th December 2011, 21:43
I have a simple and typical example :


int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
.....
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow)
{
ui->setupUi(this);
new_panel= new A_panel(this);
new_panel->w_setup();
}

- The A_panel w_setup is the method which have to do things when Qmainwindow was visible.
- The MY_qtutil().w_tell_me_the_mainwindow() returns the QMainwindow (I'm sure).
- I think that the problem can be related with I cant do processevents until a.exec() has reached . (I have read something related)

Now I'm doing a test using a Qtimer with an intervla of 1 ms. After 16 ms. I have the QmainWindow already visible .
What is your opinion ? Thanks

d_stranz
7th December 2011, 22:05
The QAppliccation main event loop does not start until line 6 (a.exec()), so inside your MainWindow constructor there is no event loop yet. In addition, MainWindow "w" is actually not visible when you call w.show() in line 5, but only become visibles when the event loop starts in line 6.

So basically, nothing happens in A_panel::setup() because 1) there is no event loop and 2) your MainWindow constructor has never exited (you jumped out of it to call A_panel::setup() and your processEvents loop never exits), so you will never get to lines 5 or 6.

The way you use a QTimer is not good, because the timing will depend on the PC and on the load of other processes running at the time. So maybe 16ms is OK one time, but not good another time. You can use QTimer a different way.

Implement a slot for your MainWindow class:



// .h
class MainWIndow //...
{
protected slots:
void onStart();

//...
};

// .cpp

MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);

QTimer::singleShot( 0, this, SLOT( onStart() );
}


void MainWindow::onStart()
{
new_panel= new A_panel(this);
new_panel->w_setup();
}


The timer will be started with a zero timeout just before the MainWindow constructor exits. However, because the event loop isn't running yet, the timeout() signal can't be processed until the event loop starts. After you call a.exec(), the event loop is then running and the timeout signal will get queued up. The MainWindow isn't necessarily visible in onStart(), but I think the event loop in w_setup() should probably work then and eventually the MainWindow will become visible.