I am new to QT GUI programming and I am using QT Creator. The problem I am seeing is with my pushbutton and line edit when the user presses the enter key. My program opens a groupbox and allows the user to enter a password and press ok or cancel.
If the user presses the enter key when the line edit has focus, the program seems to emit a second signal for QAbstractButton animateClick(); So when the next group box opens and prompts the user to press ok or cancel, the program continues as if the user pressed the ok button.
I set up my Push buttons to allow the user to press the tab key and hit the enter key. In order to obtain this functionality I set okbutton->setAutodefault(true); and cancelButton->setAutodefault(true);
I also have a lineEdit for the user to enter a password and press enter. I set this up by connecting the return pressed signal to the ok button shown below.
connect(lineEdit, SIGNAL(returnPressed()), okButton, SIGNAL(clicked()));
I also tried to connect return pressed signal directly to the slot but the problem still occurs.
connect(lineEdit, SIGNAL(returnPressed()), this, SLOT(chkPassword()));
If the user clicks the okButton with the mouse or I set okButton->setAutoDefault(false); the program functions as it should. I would like to know if it is possible to disable the animateClick signal that occurs when the line edit has focus.
Any help with this would be greatly appreciated.
Try never connecting lineEdit with the okButton, i.e. comment out this line in your code:
connect(lineEdit, SIGNAL(returnPressed()), okButton, SIGNAL(clicked()));
and check if the program behaves as you want it to.
Also, you might want to call
okButton->setDefault(true);
in addition to your setAutoDefault() calls on both buttons, depending on what exactly you want to happen when the user presses Enter with various things in focus. See this answer for more information on this subject.
I assume, since you never mention it, that you do not call setDefault() for any of your buttons. Thus, okButton is your first button with the autoDefault property set to true. This means that okButton becomes the dialog's "button of choice" whenever the dialog has to handle an Enter keypress that did not happen on some other autoDefault button (such as cancelButton in your case).
Everytime any widget in your dialog receives an Enter keypress and does not consume the event itself, the event ends up being handled by the dialog's default-button handling logic, which results in a click on the aforementioned "button of choice".
QLineEdit is not used for multi-line editing, so it probably just does not consume the key press event for Enter (while still handling it, in that it sends outs the returnPressed() signal). Thus, your connection of returnPressed() ends up doing whatever it is doing, and, additionaly, the default-button logic ends up clicking your button a second time.
Also check out this thread on the Qt project forums which seems to solve the same problem differently.
Related
I have a CFormView Dialog with Buttons to send commands for a hardware I/O.
I the user accidentally click the enter key, the command is executed. (the last button one, that has the focus).
How do you solve this in the correct way?
The way ist to use PreTranslateMessage. CHeck for WM_KEYDOWN and VK_ENTER. Ignore it or do whatever you want.
Background: CFormView::PreTranslateMessage later calls PreTranslateInput and this finally calls IsDialogMessage and this functions translates the Enter key to execute the default dialog button.
I want to create a behavior in which when I finished editing a text, the focus either moves to the next child or clear the focus on the current field when I pressed "Enter". I would then get one signal to trigger a part of the code.
When I do editingFinished() and reimplement keyReleaseEvent() for "Enter" with focusNextChild() or clearFocus(), I get two signals for the text edit, one when the "Enter" is pressed, and one when the focus is change via focusNextChild() or clearFocus(). The extra signal is undesirable.
If I do returnPressed() and reimplement keyReleaseEvent() for "Enter" with focusNextChild() or clearFocus(), it would only create one signal, but I also want the signal to be created when the user exits the lineEdit via tab() or mouse click on any other line items, which would not be the case if I use returnPressed()
Ideally, I could use a signal when a lineEdit loses focus, its connected to a slot that runs the code and I can reimplement the keyReleaseEvent() for "Enter" to set the focus, but it doesn't seem like such a signal exists in Qt.
Does anyone have recommendations on how to implement this or a better way to approach it?
You can connect/disconnect signals when you want. For example, when you focus in the QLineEdit you can connect both listed signals to slot which will disconnect those two connections and move focus to the next child. Thus, you will have only one signal processed.
Another solution - you can call QLineEdit.blockSignals(true) in the beginning of the slot and call QLineEdit.blockSignals(false) in the end of the slot. In this case whatever you do in the slot you will not trigger any signal in QLineEdit and no duplicates will arise.
My goal is to have two buttons, "Cancel" and "Connect", and to have Cancel be the default button when the user presses ENTER. I also want the user to be able to TAB to the next button ("Connect") and press ENTER and have "Connect" get pushed. Here's my code:
QPushButton * cancelButton = new QPushButton(tr("&Cancel"));
cancelButton->setAutoDefault(true);
cancelButton->setDefault(true);
cancelButton->setFocus();
QPushButton * continueButton = new QPushButton(tr("Co&nnect"));
continueButton->setAutoDefault(true);
continueButton->setDefault(false);
ui->buttonBox->addButton(cancelButton, QDialogButtonBox::RejectRole);
ui->buttonBox->addButton(continueButton, QDialogButtonBox::AcceptRole);
Setting the Cancel button to the the default button doesn't actually seem to work.
Setting the autoDefault property on all the butons seems to be necessary in allow the buttons to get pushed after pressing TAB and ENTER for example. This seems to jive with the documentation for autoDefault. However, the documentation for the default property seems to indicate that the default button will get pushed only if there are no buttons that have the autoDefault property set. Otherwise, the button that gets pushed when ENTER is pressed will be the currently selected autoDefault button. So it seems like what I need to do is to make the cancelButton have focus by default, but I can't seem to figure out how to do this.
You have to call cancelButton->setFocus(); after adding the buttons to the QDialogButtonBox, not before.
Try adding below line before you call dialog->show
button->isEnabled(true)
I've written a Qt GUI which contains some QSpinBoxes and QDoubleSpinBoxes, among other stuff. Everything works as intended, except for one thing: when I enter a number into the QSpinBoxes and finish the entry by pressing the "Enter" key, this also activates the first widget in the tab order: i.e. instead of just changing the value of my spin box, I'm also pressing the button at the top of my dialog - which I don't want. How can I fix this? (Note that I need to press Enter for the new value to be accepted, because the spin boxes' keyboard tracking is deactivated.)
EDIT: In case someone comes across a similar problem: http://developer.qt.nokia.com/doc/qt-4.8/eventsandfilters.html
I think what might be happening is the default button of a QDialog is being pressed when you press Enter.
If you are subclassing QDialog yourself, then one of your QPushButtons has it's default property set to true. If you revert that to false, then the button will not react to the Enter key unless in focus. The disadvantage here, is that your dialog can't be dismissed by pressing Enter, if you want to stick with the default values for example.
In my QMenuBar, I have several menus.
One of those menus has a QWidgetAction in it.
It shows up fine, but the problem is that once the user completes his input, I want the menu to disappear (as is the normal behavior for a classical QAction).
However, I am not sure on how to do that. In my QWidgetAction, there is a button the user presses when he is done; I can therefore bind to this button's clicked() signal.
In the slot, I tried to setFocus() an element outside the menu but the menu still doesn't disappear.
How to tell the menu to close itself when my users finish interacting with the QWidgetAction?
Thanks
QMenu inherits QWidget, so calling yourMenu->hide() should do the work.
Hope this helps.