Results 1 to 9 of 9

Thread: UI change vs. programmatic change

  1. #1
    Join Date
    Sep 2011
    Posts
    9
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Thanks
    1

    Default UI change vs. programmatic change

    Using Qt 4.7.3 and Designer, I placed a spin box in a group box.
    In code, when a user makes a change, the value is sent away. When a reply comes back the spin box is written again.
    Sometimes an external value change arrives asynchronously.

    Qt Code:
    1. void MyGroupBox::on_MySpinBox_valueChanged(double d)
    2. {
    3. // (other code)
    4. emit(signal_MyMessage(d));
    5. }
    6.  
    7. void MyGroupBox::slot_MyExternalValue(double d)
    8. {
    9. // (other code)
    10. ui->MySpinBox->setValue(d);
    11. }
    To copy to clipboard, switch view to plain text mode 

    The only relevant signals from a spin box are "editingFinished" or "valueChanged". EditingFinished isn't triggered by the buttons.
    I've fiddled quite a bit but can't find a direct way to distinguish the source of the change.
    The abstract spinner and other base classes can see mouse presses and other events, but I'm stumbling over the fact that Designer does all its work from within the group box with "ui->".
    Sorry this seems like a common programming thing to want to do, and likely another case of C++ ignorance--patience, please.

    Thanks, Scott

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

    Default Re: UI change vs. programmatic change

    So what's the problem exactly?
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  3. #3
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,729
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Wiki edits
    17

    Default Re: UI change vs. programmatic change

    I think the spin box value is changing in a way ScottBell is not expecting.

    Here are some general options:
    • Put a breakpoint in the slot that is accepting a value. When it stops there follow the stack backtrace back until you find the emitter.
    • In the slot output the sender()->objectName() and this may shed some light


    Consider the possibility of a loop:
    1. The spin box changes due to user action causing a signal
    2. That signal cause some external processing that emits a signal
    3. That signal is connected to your slot which potentially changes the spin box value again
    4. ... causing the original signal to be sent again: See 2.

  4. #4
    Join Date
    Sep 2011
    Posts
    9
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Thanks
    1

    Default Re: UI change vs. programmatic change

    Wysota, I see now the issue wasn't clear amid the other info.
    ChrisW67 correctly described one of the symptoms I needed to work around.

    Here's another manifestation, disregarding the possible loop problem for now:

    1. Say the user changes the value, directly or with buttons.
    2. The box is updated and the valueChanged signal emitted.
    3. My slot gets the value, makes some decisions and sends it away.

    Later after processing, or maybe from an unrelated event...

    4. A message arrives to update the box.
    5. setValue() also emits the valueChanged signal.
    That all makes sense.


    QUESTION:
    Can you suggest an easy way to identify where the change came from?
    or
    An elegant way to block the spin box signal while doing the programmatic change?

    I tried using the editingFinished signal but it is not asserted by the spin arrows.


    Currently I am using a clunky workaround that's not bulletproof - In the code module that handles all this, set a bool just before doing a programmatic update. The valueChanged slot checks its state and sees it was not from the UI, then clears the bool before exiting.

    It's at this point where I'm embarrassed over poor C++ fluency. The spin box is subclassed and exposes only a few methods directly. Some functions in the abstract spin box look helpful.

    This is where things get blurry. Mine was built in Designer and with a group box around it, so Qt code accesses it as ui->mySpinBox->(). Example code is usually not generated by Designer, or doesn't have layered widgets or doesn't often show overrides. As noobs have stated elsewhere, it must be so easy...

    Scott

  5. #5
    Join Date
    Aug 2009
    Location
    Greece
    Posts
    69
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Thanks
    2
    Thanked 14 Times in 14 Posts

    Default Re: UI change vs. programmatic change

    Can you suggest an easy way to identify where the change came from?
    http://doc.qt.nokia.com/4.7-snapshot...ct.html#sender
    but this is not elegant and not suitable for multithread apps.

    http://doc.qt.nokia.com/4.7-snapshot/qsignalmapper.html
    but this is not simple for a begginner I think.

    An elegant way to block the spin box signal while doing the programmatic change?
    disconnect the signal, set the value, reconnect the signal
    Qt Code:
    1. void MyGroupBox::slot_MyExternalValue(double d)
    2. {
    3. // (other code)
    4. disconnect(ui->MySpinBox);
    5. ui->MySpinBox->setValue(d);
    6. connect(ui->MySpinBox,SIGNAL(valueChanged(double)),this,SLOT(on_MySpinBox_valueChanged(double)));
    7. }
    To copy to clipboard, switch view to plain text mode 

  6. #6
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,729
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Wiki edits
    17

    Default Re: UI change vs. programmatic change

    An elegant way to block the spin box signal while doing the programmatic change?
    QObject::blockSignals(), just make sure that it gets enabled again.

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

    Default Re: UI change vs. programmatic change

    First I would like to know why you want to know the source of the change.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  8. #8
    Join Date
    Sep 2011
    Posts
    9
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Thanks
    1

    Default Re: UI change vs. programmatic change

    Wysota,
    ...and thanks to the others who replied,

    The UI-entered value is sent away via TCP/IP to an external device.
    The external device may act on the new value or may reject it because of various conditions.
    The external device can also get a new value from other users, and my UI must immediately display that new value.

    When the program gets a message from the external device and the UI is updated, the spin box signal is just like a local user change. The slot then sends a TCP/IP message to the external device, causing the loop described by ChrisW67. To prevent this, I must know that the external message caused the UI update so the slot won't send out a new message.

    One idea was to test and compare the external value before doing a setValue(). If identical then there's no need to rewrite the spin box. This is a good idea to reduces repainting and is always done anyway.
    But (there is always a "but"...) comparing the external value isn't enough because a local user can re-type the value that's currently in the spin box.
    Or the local user and external message can both try to update the box at the same time.

    For now the solution I'll work with is to disconnect or block before an external setValue() operation. That isn't multi-task friendly, so there's a risk of something naughty happening.
    I don't see forum instructions to mark 'solved', but consider it so - other comments are still welcome.
    Scott

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

    Default Re: UI change vs. programmatic change

    When you receive a value from the network, store the value somewhere as the last one the network reported it had. Then set the value on the spinbox. When the widget signals, compare the value received from the signal with the one last seen on the network. If they are different, transmit the value, otherwise ignore it as the remote end already has it set. Of course when you transmit, also overwrite the stored value.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


Similar Threads

  1. DockWidgetArea change and layout direction change
    By mstegehu in forum Qt Programming
    Replies: 1
    Last Post: 21st February 2012, 22:24
  2. programmatic way to determine if in a macro
    By shevitz in forum Qt Programming
    Replies: 6
    Last Post: 2nd December 2010, 22:20
  3. QSqlTableModel programmatic changes
    By jtdavidson in forum Newbie
    Replies: 3
    Last Post: 13th July 2010, 04:29
  4. Replies: 8
    Last Post: 15th May 2007, 10:21

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
  •  
Qt is a trademark of The Qt Company.