Je veux rendre mon application portable. Je peux tabuler partout, mais si je tabule sur un QPushButton je ne peux pas appuyer dessus avec Enter, seulement avec space.
Quel est le problème? Comment le rendre pressable pour Enter?
QPushButton
.autoDefault
ou default
.La plupart des cas, la principale différence entre autoDefault
et default
est la façon dont le bouton sera rendu. Mais il y a des cas où cela peut provoquer des choses inattendues.Pour plus d'informations, lisez la suite ci-dessous.
Chaque QPushButton
possède 3 propriétés qui ne sont pas héritées. Parmi ceux-ci, deux (default
et autoDefault
) ont un rôle majeur lorsque nous plaçons des boutons sur QDialog
s, car ces paramètres (et le focus sur l'un des boutons) décident lesquels bouton sera enfoncé si nous frappons Enter.
Toutes ces propriétés sont définies comme fausses par défaut. La seule attente est autoDefault
qui sera vraie si le bouton a un parent QDialog
.
Chaque fois que vous appuyez sur space le bouton avec le focus sera pressé. Les éléments suivants décrivent ce qui se passe si vous appuyez sur Enter.
Si cela est défini sur true, le bouton sera un bouton par défaut .
Si Enter est enfoncé dans la boîte de dialogue, ce bouton sera enfoncé, sauf lorsque le focus est sur un bouton autoDefault.
Il ne devrait y avoir qu'un seul bouton par défaut. Si vous en ajoutez plus, le dernier ajouté sera le bouton par défaut.
Si cela est défini sur true, le bouton sera un bouton autoDefault .
Si Enter est enfoncé dans la boîte de dialogue, alors ce bouton sera enfoncé si le focus est dessus.
Si le focus n'est pas sur un bouton autoDefault et qu'il n'y a pas de bouton par défaut, le bouton autoDefault suivant sera enfoncé pendant Enter.
Si cela est défini sur true, la bordure du bouton ne sera pas augmentée.
Les tableaux suivants montrent quel bouton sera pressé avec différents boutons sur différents focus. Les boutons sont ajoutés de gauche à droite.
Le code suivant est un moyen d'ajouter des boutons à une boîte de dialogue. Il peut être utilisé pour tester en modifiant les valeurs boolean
dans setDefault()
et/ou setAutoDefault()
.
Il vous suffit de créer une fenêtre, d'ajouter un QPushButton
appelé pushButton
et un QLabel
appelé label
(c'est le nom par défaut) . N'oubliez pas de #include <QMessageBox>
. Copiez ensuite ce code dans le signal clicked()
du bouton:
void MainWindow::on_pushButton_clicked()
{
QMessageBox msgBox;
QPushButton button("Button");
button.setDefault(false);
button.setAutoDefault(false);
msgBox.addButton(&button, QMessageBox::ActionRole);
QPushButton autodefaultbutton("AutoDefault Button");
autodefaultbutton.setDefault(false);
autodefaultbutton.setAutoDefault(true);
msgBox.addButton(&autodefaultbutton, QMessageBox::ActionRole);
QPushButton autodefaultbutton2("AutoDefault Button2");
autodefaultbutton2.setDefault(false);
autodefaultbutton2.setAutoDefault(true);
msgBox.addButton(&autodefaultbutton2, QMessageBox::ActionRole);
QPushButton defaultbutton("Default Button");
defaultbutton.setDefault(true);
defaultbutton.setAutoDefault(false);
msgBox.addButton(&defaultbutton, QMessageBox::ActionRole);
msgBox.exec();
if (msgBox.clickedButton() == &button) {
ui->label->setText("Button");
} else if (msgBox.clickedButton() == &defaultbutton) {
ui->label->setText("Default Button");
} else if (msgBox.clickedButton() == &autodefaultbutton) {
ui->label->setText("AutoDefault Button");
} else if (msgBox.clickedButton() == &autodefaultbutton2) {
ui->label->setText("AutoDefault Button2");
}
}
Si vous compilez le code, vous pouvez obtenir cette fenêtre. Vous n'avez même pas besoin de cliquer sur les boutons car la façon dont ils sont rendus par le système d'exploitation montre lequel sera pressé si vous appuyez sur Enter ou space.
La plupart de cette réponse a été faite selon la documentation officielle.
La documentation QPushButton faite par Qt déclare ceci:
Les boutons par défaut et par défaut définissent ce qui se passe lorsque l'utilisateur appuie sur Entrée dans une boîte de dialogue.
Un bouton avec cette propriété définie sur true (c'est-à-dire le bouton par défaut de la boîte de dialogue) sera automatiquement enfoncé lorsque l'utilisateur appuiera sur Entrée, à une exception près: si un bouton autoDefault a actuellement le focus, le bouton autoDefault est enfoncé. Lorsque la boîte de dialogue contient des boutons autoDefault mais pas de bouton par défaut, appuyez sur Entrée pour appuyer sur le bouton autoDefault qui a actuellement le focus ou, si aucun bouton n'a le focus, sur le bouton autoDefault suivant dans la chaîne de focus.
Dans une boîte de dialogue, un seul bouton poussoir à la fois peut être le bouton par défaut. Ce bouton est ensuite affiché avec un cadre supplémentaire (selon le style de l'interface graphique).
Le comportement par défaut des boutons n'est fourni que dans les boîtes de dialogue. Les boutons peuvent toujours être cliqués à partir du clavier en appuyant sur la barre d'espace lorsque le bouton est actif.
Si la propriété par défaut est définie sur false sur le bouton par défaut actuel alors que la boîte de dialogue est visible, une nouvelle valeur par défaut sera automatiquement attribuée la prochaine fois qu'un bouton poussoir de la boîte de dialogue recevra le focus.
Il vaut également la peine de vérifier QDialog et QMessageBox .
Selon la documentation de Qt, Enter devrait fonctionner
Les boutons de commande dans les boîtes de dialogue sont par défaut des boutons par défaut automatiques, c'est-à-dire qu'ils deviennent automatiquement le bouton poussoir par défaut lorsqu'ils reçoivent le focus d'entrée du clavier. Un bouton par défaut est un bouton poussoir qui est activé lorsque l'utilisateur appuie sur la touche Entrée ou Retour dans une boîte de dialogue. Vous pouvez changer cela avec setAutoDefault ().
la réponse de totymedli est excellente. J'ai ajouté un petit programme pour tester différentes combinaisons de fonctions isDefault, autoDefault, setDefault et setAutoDefault.
import sys
from PyQt4.QtGui import *
from PyQt4.QtCore import *
class Window(QDialog):
def __init__(self, parent=None):
super(Window, self).__init__(parent)
autoDefaultInitialState = True
defaultInitialState = False
self.lineEdit1 = QLineEdit(self)
self.lineEdit2 = QLineEdit(self)
self.lineEdit3 = QLineEdit(self)
# if we create a new button (e.g. "Print state"), with the same function,
# it doesn't work, because adding a new button (apart from our 3 buttons)
# produces total mess, so we use this lineedit for this purpose
self.lineEdit1.returnPressed.connect(self.printState)
#------------------------------------
self.chkAutoDefaultOk = QCheckBox('OK setAutoDefault', self)
self.chkAutoDefaultCancel = QCheckBox('Cancel setAutoDefault', self)
self.chkAutoDefaultApply = QCheckBox('Apply setAutoDefault', self)
self.chkDefaultOk = QCheckBox('OK setDefault', self)
self.chkDefaultCancel = QCheckBox('Cancel setDefault', self)
self.chkDefaultApply = QCheckBox('Apply setDefault', self)
self.chkAutoDefaultOk.setChecked(autoDefaultInitialState)
self.chkAutoDefaultCancel.setChecked(autoDefaultInitialState)
self.chkAutoDefaultApply.setChecked(autoDefaultInitialState)
self.chkDefaultOk.setChecked(defaultInitialState)
self.chkDefaultCancel.setChecked(defaultInitialState)
self.chkDefaultApply.setChecked(defaultInitialState)
#------------------------------------
self.pushButtonOk = QPushButton(self)
self.pushButtonOk.setText("Ok")
self.pushButtonOk.clicked.connect(lambda : print('ok'))
self.pushButtonCancel = QPushButton(self)
self.pushButtonCancel.setText("Cancel")
self.pushButtonCancel.clicked.connect(lambda : print('cancel'))
self.pushButtonApply = QPushButton(self)
self.pushButtonApply.setText("Apply")
self.pushButtonApply.clicked.connect(lambda : print('apply'))
#------------------------------------
self.pushButtonOk.setAutoDefault(autoDefaultInitialState)
self.pushButtonCancel.setAutoDefault(autoDefaultInitialState)
self.pushButtonApply.setAutoDefault(autoDefaultInitialState)
self.pushButtonOk.setDefault(defaultInitialState)
self.pushButtonCancel.setDefault(defaultInitialState)
self.pushButtonApply.setDefault(defaultInitialState)
#------------------------------------
self.chkAutoDefaultOk.stateChanged.connect(self.chkChangeState)
self.chkAutoDefaultCancel.stateChanged.connect(self.chkChangeState)
self.chkAutoDefaultApply.stateChanged.connect(self.chkChangeState)
self.chkDefaultOk.stateChanged.connect(self.chkChangeState)
self.chkDefaultCancel.stateChanged.connect(self.chkChangeState)
self.chkDefaultApply.stateChanged.connect(self.chkChangeState)
#------------------------------------
self.layout = QGridLayout(self)
self.layout.addWidget(self.lineEdit1, 0, 0, 1, 3)
self.layout.addWidget(self.lineEdit2, 1, 0, 1, 3)
self.layout.addWidget(self.lineEdit3, 2, 0, 1, 3)
self.layout.addWidget(self.chkAutoDefaultOk, 3, 0)
self.layout.addWidget(self.chkAutoDefaultCancel, 3, 1)
self.layout.addWidget(self.chkAutoDefaultApply, 3, 2)
self.layout.addWidget(self.chkDefaultOk, 4, 0)
self.layout.addWidget(self.chkDefaultCancel, 4, 1)
self.layout.addWidget(self.chkDefaultApply, 4, 2)
self.layout.addWidget(self.pushButtonOk, 5, 0)
self.layout.addWidget(self.pushButtonCancel, 5, 1)
self.layout.addWidget(self.pushButtonApply, 5, 2)
def chkChangeState(self):
obj = self.sender()
if (obj == self.chkAutoDefaultOk):
self.pushButtonOk.setAutoDefault(self.chkAutoDefaultOk.isChecked())
Elif (obj == self.chkAutoDefaultCancel):
self.pushButtonCancel.setAutoDefault(self.chkAutoDefaultCancel.isChecked())
Elif (obj == self.chkAutoDefaultApply):
self.pushButtonApply.setAutoDefault(self.chkAutoDefaultApply.isChecked())
Elif (obj == self.chkDefaultOk):
self.pushButtonOk.setDefault(self.chkDefaultOk.isChecked())
Elif (obj == self.chkDefaultCancel):
self.pushButtonCancel.setDefault(self.chkDefaultCancel.isChecked())
Elif (obj == self.chkDefaultApply):
#print('sender: self.chkDefaultApply')
#print('before: ', self.pushButtonApply.isDefault())
self.pushButtonApply.setDefault(self.chkDefaultApply.isChecked())
#print('after: ', self.pushButtonApply.isDefault())
def printState(self):
print(self.pushButtonOk.autoDefault(), self.pushButtonCancel.autoDefault(), self.pushButtonApply.autoDefault())
print(self.pushButtonOk.isDefault(), self.pushButtonCancel.isDefault(), self.pushButtonApply.isDefault())
print('-' * 50)
app = QApplication(sys.argv)
main = Window()
main.show()
sys.exit(app.exec_())