Page 1 of 2 12 LastLast
Results 1 to 20 of 23

Thread: mainwindow does not refresh

  1. #1
    Join Date
    Jan 2006
    Posts
    25
    Thanked 1 Time in 1 Post
    Qt products
    Qt3
    Platforms
    Unix/X11 Windows

    Default mainwindow does not refresh

    I have a mainwindow that is derived from QMainwindow and that uses a number of dockwindows and has qworkspace as its central widget (for MDI purposes). Some of the processes I run are very lengthy. If I minimize my application to do something meanwhile, the mainwindow does not refresh on showing. I tryed to force this using the following timer (code in constructor of mainwindow):

    Qt Code:
    1. QTimer *refreshTimer = new QTimer( this );
    2. connect( refreshTimer, SIGNAL( timeout() ), this, SLOT( SlotRefresh() ));
    3. refreshTimer->start( 100, FALSE );
    To copy to clipboard, switch view to plain text mode 

    SlotRefresh(): tryed it with update and repaint:

    Qt Code:
    1. void mainwindow::SlotRefresh()
    2. {
    3. /*update();
    4.   qApp->processEvents();*/
    5. repaint();
    6. qApp->processEvents();
    7. }
    To copy to clipboard, switch view to plain text mode 

    I even tryed to call update on one of the dockwindows used, but that doesn't work either

    Any ideas?

    Thanx

  2. #2
    Join Date
    Jan 2006
    Location
    Munich, Germany
    Posts
    4,714
    Thanks
    21
    Thanked 418 Times in 411 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: mainwindow does not refresh

    it doesn't work since your solution doesn't deal with the problem which is that the legthy task doesn't gives the main event loop a chance to process the timer event, to the same reason your main windwos does not refresh is resposible for the timer slot not to work (actually the timer signal not to be processed).

    You need to inser processEvents in your lengthy process, thats all.
    Then you can delete the QTimer thing.

  3. #3
    Join Date
    Jan 2006
    Posts
    25
    Thanked 1 Time in 1 Post
    Qt products
    Qt3
    Platforms
    Unix/X11 Windows

    Default Re: mainwindow does not refresh

    The problem is that the lengthy process is one out of a library we use, which is a non QT library. Is it possible to call the processEvents somehwhere else? Maybe by working with threads (must admit I don't like threads, but if nothing else is possible...).

  4. #4
    Join Date
    Jan 2006
    Location
    Munich, Germany
    Posts
    4,714
    Thanks
    21
    Thanked 418 Times in 411 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: mainwindow does not refresh

    Is it possible to call the processEvents somehwhere else?
    Sure, but will it help?
    Maybe by working with threads (must admit I don't like threads, but if nothing else is possible...).
    Yes, it sounds that threads are the solution in this case.
    Create a new thread and call your lengthy process in that thread, and send an event when its finished back to the main thread, this will alow your GUI to stay resposive

  5. #5
    Join Date
    Jan 2006
    Posts
    25
    Thanked 1 Time in 1 Post
    Qt products
    Qt3
    Platforms
    Unix/X11 Windows

    Default Re: mainwindow does not refresh

    I put my lengthy process in a thread and now the refreshing works but the widget from which the thread was started should be disabled during the execution of the thread. With refreshing I only mean the visual aspect, ie the widget shows all its colors and buttons. It may not seem as if it crashed.

    How can I do this? Can I disable the widget and if so: how do I check whether the thread has finished. I tryed putting a loop after starting the thread that does nothing and only exits when finished() is true, but that didn't work:

    Qt Code:
    1. while (!myThread.finished())
    2. {
    3. }
    To copy to clipboard, switch view to plain text mode 

    How can I let my main program wait for the thread to finish whithout loosing the refreshing of the main window?

  6. #6
    Join Date
    Jan 2006
    Location
    Germany
    Posts
    52
    Thanks
    1
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: mainwindow does not refresh

    You could create also a timer. The timer should fire every second or so, and then check the worker thread. If the thread is done, the time could raise an event or some other means to tell your app that the thread has finished.

  7. #7
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    5,372
    Thanks
    28
    Thanked 976 Times in 912 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: mainwindow does not refresh

    Quote Originally Posted by Mike
    You could create also a timer. The timer should fire every second or so, and then check the worker thread. If the thread is done, the time could raise an event or some other means to tell your app that the thread has finished.
    You don't need timers --- thread can posts such event when it finishes.

  8. #8
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: mainwindow does not refresh

    Or even emit a signal.

  9. #9
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    5,372
    Thanks
    28
    Thanked 976 Times in 912 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: mainwindow does not refresh

    Quote Originally Posted by wysota
    Or even emit a signal.
    In Qt3?

  10. #10
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: mainwindow does not refresh

    Quote Originally Posted by jacek
    In Qt3?
    I was speaking in general terms. QThread in Qt3 doesn't provide a signal for that, but you still can emit one (by sending an event, processing it and emitting a signal from the thread using the custom event handler and a wrapper (like void MyThread::emitFinished(){ emit finished(); })
    Last edited by wysota; 23rd January 2006 at 19:29.

  11. #11
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    5,372
    Thanks
    28
    Thanked 976 Times in 912 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: mainwindow does not refresh

    Quote Originally Posted by wysota
    QThread in Qt3 doesn't provide a signal for that
    Because QThread doesn't inherit QObject in Qt3. You would have to use multiple inheritance.

  12. #12
    Join Date
    Jan 2006
    Location
    Athens - Greece
    Posts
    219
    Thanks
    3
    Thanked 1 Time in 1 Post
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: mainwindow does not refresh

    Read the docs on QThread, the examples given are enough for your case. You just have to post an event to the main / gui thread to alert it that the operation has finished. The GUI programming with qt3 book also has some very usefull examples.

  13. #13
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: mainwindow does not refresh

    Quote Originally Posted by jacek
    Because QThread doesn't inherit QObject in Qt3. You would have to use multiple inheritance.
    Hmm... true, I didn't notice that.

  14. #14
    Join Date
    Jan 2006
    Location
    Mountain View, CA
    Posts
    279
    Thanked 42 Times in 37 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: mainwindow does not refresh

    Quote Originally Posted by edb
    I put my lengthy process in a thread and now the refreshing works but the widget from which the thread was started should be disabled during the execution of the thread. With refreshing I only mean the visual aspect, ie the widget shows all its colors and buttons. It may not seem as if it crashed.

    How can I do this? Can I disable the widget and if so: how do I check whether the thread has finished. I tryed putting a loop after starting the thread that does nothing and only exits when finished() is true, but that didn't work:

    Qt Code:
    1. while (!myThread.finished())
    2. {
    3. }
    To copy to clipboard, switch view to plain text mode 

    How can I let my main program wait for the thread to finish whithout loosing the refreshing of the main window?

    Your while loop is blocking the main thread which is causing the same problem you had before. Here is some partial code that describes what you need to do. Look at the QThread and QWidget docs to see about posting events from a secondary thread to the main thread.

    Qt Code:
    1. // Main(GUI) thread
    2.  
    3. // Constructor/destructor of MainWindow, etc.
    4.  
    5. ...
    6. ...
    7.  
    8. MainWindow::startJob()
    9. {
    10. // Disable whole window
    11. setEnabled(false);
    12.  
    13. // Launch thread
    14. mpWorkerThread = new WorkerThread();
    15.  
    16. mpWorkerThread.start();
    17. }
    18.  
    19.  
    20. MainWindow::stopJob()
    21. {
    22. // Enable whole window
    23. setEnabled(true);
    24.  
    25. // Do any other cleanup here
    26. }
    27.  
    28.  
    29. Mywidget::customEvent(QCustomEvent* e)
    30. {
    31. // Decode e here and check if it is your special worker custom event
    32. if (int(e->type()) == MY_CUSTOM_EVENT_ID)
    33. stopJob();
    34. }
    35.  
    36.  
    37. // Worker thread code
    38.  
    39. #include <qapplication.h>
    40. #include <qevent.h>
    41.  
    42. // Init static constant
    43. WorkerThread::MY_CUSTOM_EVENT_ID = QEvent::User + 1;
    44.  
    45. // Implement constructor/destructor, etc.
    46. WorkerThread::WorkerThread(MainWindow* parent) : QThread()
    47. mpParent(parent)
    48. {
    49. }
    50.  
    51. WorkerThread::run()
    52. {
    53. // Implement worker code here
    54. while ( still_not_finished)
    55. {
    56. ...
    57. ...
    58. }
    59.  
    60. // At end of function, notify main thread that we have finished.
    61. qApp->postEvent(mpParent, new QCustomEvent(MY_CUSTOM_EVENT_ID));
    62. }
    To copy to clipboard, switch view to plain text mode 
    Last edited by Chicken Blood Machine; 25th January 2006 at 17:46.

  15. #15
    Join Date
    Jan 2006
    Posts
    25
    Thanked 1 Time in 1 Post
    Qt products
    Qt3
    Platforms
    Unix/X11 Windows

    Default Re: mainwindow does not refresh

    Thanx for all your tips. I wil try them today and keep you posted!

  16. #16
    Join Date
    Jan 2006
    Posts
    25
    Thanked 1 Time in 1 Post
    Qt products
    Qt3
    Platforms
    Unix/X11 Windows

    Default Re: mainwindow does not refresh

    I tryed this, but I keep getting a strange error:

    Xlib: unexpected async reply. I found a website which contains a description of this error:


    http://www.faqs.org/faqs/x-faq/part7/section-15.html

    It states:

    You'll typically get these errors if you are writing a multi-threaded
    application and are making X calls from more than one thread -- one of the
    more common new ways to introduce memory corruption into Xlib (using bogus
    pointers is another, as is mixing up XFree/XtFree/free calls. Even an
    operation as simple as XSendEvent can't be called from a second thread.).
    Prior to X11R6, X doesn't support multi-threading; check the X11R6
    documentation for how to write a threaded application safely with X11R6 and
    later versions of X (including being sure to enable Xlib's multi-thread
    support).
    Does this mean I cannot post events in one thread that can be received in another thread? Using the example above I want to call the qApp->postEvent from my "lengthy process thread" and receive it in my main thread.

  17. #17
    Join Date
    Jan 2006
    Location
    Mountain View, CA
    Posts
    279
    Thanked 42 Times in 37 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: mainwindow does not refresh

    You should not be having any async problems, since you should not be making iny X11 calls from another thread. Please post your code so we can see where it is going wrong.

  18. #18
    Join Date
    Jan 2006
    Posts
    25
    Thanked 1 Time in 1 Post
    Qt products
    Qt3
    Platforms
    Unix/X11 Windows

    Default Re: mainwindow does not refresh

    my main program:

    Qt Code:
    1. QApplication a(argc,argv);
    2. MyMDIMainWindowThread* mainthread = new MyMDIMainWindowThread();
    3. mainthread->start();
    4. mainthread->wait();
    5. return a.exec();
    To copy to clipboard, switch view to plain text mode 


    MyMDIMainWindowThread run:
    Qt Code:
    1. void MyMDIMainWindowThread::run()
    2. {
    3. mpMyMainWindow = new MyMDIMainWindow();
    4. mpMyMainWindow->showMaximized();
    5. qApp->setMainWidget(mpMyMainWindow);
    6. std::cout << "mainthread ended" << std::endl << std::flush;
    7. }
    To copy to clipboard, switch view to plain text mode 

    run function for thread for the lengthy process:
    Qt Code:
    1. // ... run lengthy process
    2.  
    3. //.. mpParent is set in the constructor and is a pointer to the widget that started the thread
    4. qApp->postEvent(mpParent, new QCustomEvent(MyThread::PROCESSTHREADENDED));
    To copy to clipboard, switch view to plain text mode 

    customEvents function:
    Qt Code:
    1. void MyLengthyProcessWidget::customEvent(QEvent* e)
    2. {
    3. switch (int(e->type()))
    4. {
    5. case MyThread::PROCESSTHREADENDED:
    6.  
    7. {
    8. // the messagebox is never shown!
    9. QMessageBox::critical(0, tr(""),tr("Process Thread Ended!!!"), QMessageBox::Ok,0,0);
    10. setEnabled(true);
    11. break;
    12. }
    13. }
    To copy to clipboard, switch view to plain text mode 

    finally: starting the lengthy process thread from a function in MyLengthyProcessWidget::
    Qt Code:
    1. setEnabled(false);
    2. MyLengthyProcessThread* proc = new MyLengthyProcessThread(this);
    3. proc->start();
    To copy to clipboard, switch view to plain text mode 

    Think that's all....

  19. #19
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: mainwindow does not refresh

    You can't do GUI operations from a thread which does not own QApplication object.

    And looking at your code... why do you need that thread if you put your main application thread to sleep after you spawn it?

    I'm talking about this:

    Qt Code:
    1. QApplication a(argc,argv);
    2. MyMDIMainWindowThread* mainthread = new MyMDIMainWindowThread();
    3. mainthread->start();
    4. mainthread->wait();
    5. return a.exec();
    To copy to clipboard, switch view to plain text mode 

  20. #20
    Join Date
    Jan 2006
    Location
    Mountain View, CA
    Posts
    279
    Thanked 42 Times in 37 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: mainwindow does not refresh

    @edb - I think you misunderstood my post. (or maybe I wasn't completely clear!)

    When I referred to the main thread, I meant the main thread of execution (where the program starts). You do not need to create a 'main thread'. This is why you are getting those async errors.

    I've tried to correct your code to put you on the right track:

    Qt Code:
    1. int main(int argc, char** argv)
    2. {
    3. QApplication a(argc,argv);
    4. MyMDIMainWindow* mainwindow = new MyMDIMainWindow();
    5. mainwindow ->show();
    6. a.setMainWidget(mainwindow);
    7. return a.exec();
    8. }
    To copy to clipboard, switch view to plain text mode 


    MyMDIMainWindow startSlot() - called in response to whatever is required to
    start your lenthy process, e.g. button press, etc:
    Qt Code:
    1. void MyMDIMainWindow::startSlot()
    2. {
    3. setEnabled(false);
    4.  
    5. MyLengthyProcessThread* proc = new MyLengthyProcessThread(this);
    6. proc->start();
    7. }
    To copy to clipboard, switch view to plain text mode 

    You can also implement a stopSlot() to terminate the worker thread prematurely if required.

Similar Threads

  1. mainwindow modality
    By user in forum Qt Programming
    Replies: 0
    Last Post: 11th July 2008, 01:54
  2. Refresh the Mainwindow at run time
    By sabeesh in forum Qt Programming
    Replies: 3
    Last Post: 15th November 2007, 14:16
  3. Notifying Mainwindow of an event..
    By MrGarbage in forum Qt Programming
    Replies: 1
    Last Post: 9th November 2007, 22:29
  4. Replies: 1
    Last Post: 11th September 2007, 14:34
  5. Replies: 3
    Last Post: 23rd July 2006, 19:02

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.