QToolBox and currentChanged() signal



  • Hello;
    I'm hoping this was not discussed in depth before, since my 10min search didn't yield anything useful,
    but I'd want to avoid repeating already resolved issues. Anyways:

    How do I find out what method emits "currentChanged()", and should I be overloading this?
    What I'm trying to do is the following:

    I have a main window containing QToolBox and a status line.
    The status line is updated periodically (I send "ticks" 4x a sec).
    I'm using my own threading library. Since Qt is not really thread safe
    for whatever reason, I cannot call updates directly (I've tried, and it complains).
    Thus, I send "ticks" to a method that emits a signal that the status should be updated.
    However, the status update is context dependent (I print different info depending on the
    current tab of the QToolBox being active). I'm trying to avoid this race condition:

    tick -> signal update needed -> go into update handler -> user switches the tab -> I print a wrong status line

    I know that it's not a big deal since users won't be changing the tabs faster than once every many seconds,
    but just knowing that this race exists really bugs me.

    Any ideas how I could lock the gui and prevent changing the tab while updating the status line? Where should
    the mutex go on the GUI side?

    thanks!



  • Qt is thread safe in general.

    You must not update the GUI from outside the main thread!

    Use "queued connections":http://developer.qt.nokia.com/doc/qt-4.7/threads-qobject.html to send messages from one thread to another.

    Read "this wiki article":http://developer.qt.nokia.com/wiki/Threads_Events_QObjects


  • Moderators

    Is your other thread doing anything else besides sending the ticks?



  • [quote]
    The status line is updated periodically (I send “ticks” 4x a sec).
    I’m using my own threading library. Since Qt is not really thread safe
    for whatever reason, I cannot call updates directly (I’ve tried, and it complains).
    Thus, I send “ticks” to a method that emits a signal that the status should be updated.[/quote]

    What's this supposed to mean? Are you trying to update the GUI from a non-GUI thread? And, are you trying to use a thread as a ticker?



  • @Volker: I'll read your suggestions asap ...

    To clarify:

    1. I am not trying to update the gui outside of the gui thread.
    2. The program looks like this:

    *) gui thread (all gui stuff)
    **) a ticker thread: a "periodic" function calling a method in my class (4 times a second)
    this thread is not doing anything else ... it's a timing thread.

    What I have so far is working just fine (except that there is, I believe, a race condition).

    1. ticker calls a public method (void MyMainWindow::periodicUpdate()) inside my class

    2. this method emits a signal

    3. This signal is routed to my slot that does status updating
      (through something like:
      QObject::connect(sender, signal, receiver, method, Qt::QueuedConnection)
      which I believe will end up being what Volker is suggesting)

    4. So far so good ... i think this is all correct. This is all "context". My question is:

    Once my statusUpdate slot receives the signal it must update the status line. However,
    the contents of my status line depend on which tab in QToolBox is currently displayed.
    This is where a race condition could occur: if I enter my statusUpdate slot and "determine"
    which tab is currently displayed it could happen that the user clicks on a different tab!
    Now the gui will react and switch the tab, while my statusUpdate slot will still think that
    it should display the data for the previously selected one!

    A guard on a mutex is obviously needed. I just don't know where I could put it? I don't know
    how I can prevent the gui from accepting the input that would switch the QToolBox tab until
    the statusUpdate slot is finished executing. It's a simple problem, however not being familiar
    with Qt I'm very confused as to where I could do this.

    Thanks for your answers guys!

    ranko


  • Moderators

    I think that you will find that you are much better off just using a QTimer with a timeout of 250ms that calls your update from within the main thread. That way you don't have to worry about race conditions, timing, or any of the other artifacts that are introduced by using a separate thread.



  • Thanks, mlong!
    That is definitely worth checking out, in my case since I don't need to sync this to anything.
    Is there any solution along the lines I stated? Always good to know more than one way to
    do something ... :)


  • Moderators

    I'm sure there would be some kind of solution on the road you were on, but it would be convoluted and painful. :-)



  • [quote author="neozbiljan" date="1313715435"]
    **) a ticker thread: a "periodic" function calling a method in my class (4 times a second)
    this thread is not doing anything else ... it's a timing thread.
    [/quote]

    "When shouldn’t I use threads?":http://developer.qt.nokia.com/wiki/Threads_Events_QObjects#92dd35cc61ffc41d02defdcef071856d



  • Thanks a lot for the replies!

    Thinking about this more, I came up with this "model", please correct me if I'm wrong:

    If Qt doesn't open some "background" threads on its own, there is only one thread dealing with the GUI (in my code). Thus, no race condition can happen since only one method (whether one of mine or Qt's internal stuff) can be executed at the time within one thread. In that sense using QTimer or sending an event into the queue makes no difference since once the signal is delivered to a slot for processing no other event will be handled (as we are in the same thread)?

    Or is there more to this story? (currently reading the article :))


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.