Results 1 to 9 of 9

Thread: How to deactivate all widgets except one on form startup or show?

  1. #1
    Join Date
    Dec 2020
    Posts
    3
    Qt products
    Qt4 Qt5 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows Android

    Default How to deactivate all widgets except one on form startup or show?

    Dear everyone,
    I have designed a QDialog form on which have placed different widgets to do some calculations.
    However, everything is working according to plans.
    Except that I want to disable all widgets except one for initial input.
    I want widgets to follow tab order. After being done entering data, it should trigger or enable the next button to the end.
    Previous widgets should loose focus and become disabled as soon as am done with them. But when I click the last button, the first widget should become active again, to allow fresh entry of data.
    I used PyQt5 designer version 5.11 to design.
    Last edited by Andrew K. Kabaghe; 19th December 2020 at 14:30.

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

    Default Re: How to deactivate all widgets except one on form startup or show?

    Look into the possibility of installing an event filter on every child widget. In the filter function check for QEvent::KeyPress, QEvent::FocusOut and QEvent::FocusIn and try to weave the magic here. The main problem I see here is that a disabled widget, i.e. the next one, cannot get the keyboard focus on Tab etc. You need to enable the subsequent widget before the focus can move there, and you need to do that in response to something happening in the present widget before Qt tries to move the focus. Normally Tab keystrokes are not presented to the widget, so you will have to filter for these as well.

    If this is really a serial process you could consider using QWizard instead.

    As a data entry form I would find the behaviour you seek potentially counter-productive. For example, the form assumes nobody ever mistypes (needs to go back and correct) and forces them to complete a process with bad input.

  3. #3
    Join Date
    Dec 2020
    Posts
    3
    Qt products
    Qt4 Qt5 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows Android

    Default Re: How to deactivate all widgets except one on form startup or show?

    Thanks for your valuable response.
    The challenge I have is that in my application, there is:
    1. A QLineEdit which I may alias here as "lineEditIncome" for inputting integers which is connectected to a QPushButton (pushButtonComfirmIncome) to confirm input.
    2. Next is another QLineEdit (linEditAgentFee) for inputting integers, which has a pushButtonAgentFees for confirmation as well.
    3. This is also followed up by Radio buttons, say: a, b, c, d for other expenses.
    4. After which user has to click on two final pushbuttons for adding expenses (to two Line Edits) and calculating allowance (which is the difference between Income and all costs).

    The problem is that, if user skips any steps (eg inputting income or Agent Fees), terminates the app or if he forgets to choose one of the above radio buttons, will end up with wrong output, or if he forgets to click "Add Expense" push button which populates a "total expense" Line Edit, the program crashes as too .

    I know Event Handling can take care of that, but am not very familiar with making event handling and slotting it into the code.
    Therefore, for the time being, I wanted to deactivate all buttons and make current action enable the next in put widget.

    Maybe, in case of the wrong input as you correctly pointed out, the previous widgets shout remain active.
    In Delphi Pascal, it was easy to do that onFormShow but with Python and Qt5,11, am like a baby who is learning how to walk :'(
    Last edited by Andrew K. Kabaghe; 20th December 2020 at 09:56.

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

    Default Re: How to deactivate all widgets except one on form startup or show?

    If I am understanding you correctly then there is a distinct Confirm button for each input in sequence.

    In Designer, set only the first widgets as enabled and all other disabled (or do it in the constructor of your form class).

    Each QPushButton instance will emit a clicked() signal when the user confirms the input on an associated input box (line edit, spinbox, whatever).
    You connect that signal to a slot (in the form class). In that slot you can perform complex checks on the value and if it is good:
    • Call setEnabled(true) on the next logical widgets (editor and button)
    • Call setFocus() on the next logical editor widget
    • Call setEnabled(false) on the present editor and button widget

    As you are using Designer, you can probably rely on the automatic connections for each QPushButton clicked() signal to the parent form widget onButton1Clicked() slot where it exists. ( I assume that the Python equivalent of uic does this)

    There are other ways to handle this with a single slot using a QSignalMapper, but let's toddle before we try to walk or run.

  5. #5
    Join Date
    Dec 2020
    Posts
    3
    Qt products
    Qt4 Qt5 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows Android

    Default Re: How to deactivate all widgets except one on form startup or show?

    Thank you very much though am still wondering how and which code I may use to disable all widgets on Form startup and leave only one widget active?
    Hasn't the form got any options? I mean doesn't the form emit any signals we can manipulate to disable or enable widgets?

  6. #6
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: How to deactivate all widgets except one on form startup or show?

    I mean doesn't the form emit any signals we can manipulate to disable or enable widgets?
    If you are using Qt Designer to create the form, then set all widgets except the first one as disabled in Designer.

    I am not sure what kind of signals you would expect the form to emit. The form itself knows nothing really about the widgets it contains except for the tab order, so what can the form tell you? You have two ways to determine (yourself) what the user is doing in the form:

    1 - Events, such as focusInEvent(), focusOutEvent(), enterEvent(), leaveEvent(), etc. which occur as the user moves or changes input focus from widget to widget. These are received at the individual widget level (ie. a QLineEdit), not the form, so the only way you can watch for them is to install an event filter on the editing widgets and monitor that filter in your form widget.

    2 - Signals emitted by editing widgets when the user has finished editing, changed a selection, clicked a checkbox, etc. You can connect slots in your form widget.

    There are some things you are going to find it very difficult to control. If you have all widgets except one disabled, then if the user clicks the Tab key, likely nothing will happen since there is no enabled widget to receive the focus. And generally, you can't intercept the Tab key except by using an event filter. And even then, you can't enable the next widget in that filter so the Tab goes to it because that enable event won't get processed until after the Tab event has finished (and found nowhere to go).

    Like ChrisW67 says, you are implementing a very non-standard (and IMO very user unfriendly) UI. You would be better off using Qt's tools for validation (QValidator), completion (QCompleter), input masks, or tool tips to guide your users into making the correct inputs into your form.

    As I said above, most editing widgets have signals that tell you when something has changed. If validators or other tools don't work for you, then use those signals to see what has changed and then enable / disable other widgets as appropriate.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  7. #7
    Join Date
    Mar 2008
    Location
    Kraków, Poland
    Posts
    1,536
    Thanked 284 Times in 279 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: How to deactivate all widgets except one on form startup or show?

    Or maybe use the QWizard class ?

  8. #8
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: How to deactivate all widgets except one on form startup or show?

    Or maybe use the QWizard class ?
    That could get very tedious. In the early days of the Web, the US Postal Service implemented a system where you could register packages for shipment, pay the fees, and print the shipping label. All you had to do then was give the package to your postman when your mail was delivered.

    I used it once. On the first form, you entered the first name of the person you were sending the package to, then clicked Next and waited for the next page to show up (remember, these were dial-up modem days). Then you entered the family name, and clicked Next. Then the first line of the address, Next, the second line of the address, Next, the city, Next... It took 15 minutes or more to enter the complete address, and if you messed up, you started over.

    Linear thinking like that leads to a rigid and unfriendly UI and a horrible user experience. If the OP really needs to have fields entered and validated in a specific order, a QWizard might be a good idea but it could also lead to a nightmare like the Postal Service created.

    I think there are enough tools available with validators, completers, and so forth that the OP can have control over the sequence. The problem, as ChrisW67 said, is what happens if you make a mistake and need to go back, but the UI has locked you out because it disabled that widget?
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  9. #9
    Join Date
    Mar 2008
    Location
    Kraków, Poland
    Posts
    1,536
    Thanked 284 Times in 279 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: How to deactivate all widgets except one on form startup or show?

    Quote Originally Posted by d_stranz View Post
    Linear thinking like that leads to a rigid and unfriendly UI and a horrible user experience. If the OP really needs to have fields entered and validated in a specific order, a QWizard might be a good idea but it could also lead to a nightmare like the Postal Service created.
    With the same knife, you can slice the bread and cut your finger.

  10. The following user says thank you to Lesiok for this useful post:

    d_stranz (23rd December 2020)

Similar Threads

  1. Replies: 4
    Last Post: 18th October 2013, 18:15
  2. show another ui form
    By k.qasempour in forum Newbie
    Replies: 3
    Last Post: 16th July 2012, 12:26
  3. Replies: 7
    Last Post: 23rd May 2012, 13:00
  4. Replies: 0
    Last Post: 30th April 2012, 16:17
  5. show form
    By mattia in forum Newbie
    Replies: 2
    Last Post: 26th October 2007, 11:20

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.