у меня есть QDialog
с QDialogButtonBox
, Хорошо а также отменить кнопки активны. Иногда я отключаю или скрываю кнопку ОК в зависимости от состояния моего диалога. Кажется, что бы я ни делал, клавиша Enter всегда активирует кнопку ОК. Я действительно не хочу, чтобы это случилось. Я пытался:
И со всеми комбинациями этих вещей, указанных выше, клавиша Enter по-прежнему принимает диалог. Кто-нибудь знает, как это заблокировать? Кажется, я должен быть в состоянии заблокировать что-то столь же простое, как это?
Фильтрация событий нажатия клавиши должна выполняться в самом диалоге, потому что код, обрабатывающий пересылку Return
а также Enter
ключи к кнопке по умолчанию в QDialog::keyPressEvent
,
void Dialog::keyPressEvent(QKeyEvent *evt)
{
if(evt->key() == Qt::Key_Enter || evt->key() == Qt::Key_Return)
return;
QDialog::keyPressEvent(evt);
}
Или же
theDialog−>installEventFilter(anotherClassObject);
bool AnotherClass::eventFilter(QObject *obj, QEvent *evt)
{
if(evt->type() == QEvent::KeyPress) {
QKeyEvent *keyEvent = static_cast<QKeyEvent*>(evt);
if(keyEvent->key() == Qt::Key_Enter || keyEvent->key() == Qt::Key_Return )
return true; // mark the event as handled
}
return false;
}
QDialog имеет закрытый слот, который называется accept()
, Всякий раз, когда QDialogButtonBox испускает accepted()
(нажав клавишу возврата или нажав Ok), этот частный слот вызывается. Поэтому попробуйте отключить их.
disconnect(ui->buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
Это сработало для меня.
Проблема в том, что фильтр событий не должен быть установлен на кнопку ОК.
Если ваша кнопка ОК отключена, то она не будет получать событие ввода. Какой бы виджет не был в фокусе, будет. И если они не принимают событие ввода, то QDialog
собирается accept()
сам.
Два пути решить проблему:
1) Override QDialog::accept()
и позвоните QDialog
Принимайте метод в новом accept
функционировать только если ОК включен
void MyDialog::accept() {
if (okEnabled) {
QDialog::accept();
}
}
2) Установите фильтр событий на каждый виджет в диалоге который не принимает клавишу ввода (правка строки, …).
Фильтр событий будет выглядеть так:
class KeyPressEater : public QObject
{
Q_OBJECT
protected:
bool eventFilter(QObject *obj, QEvent *event);
};
bool KeyPressEater::eventFilter(QObject *obj, QEvent *event)
{
if (event->type() == QEvent::KeyPress) {
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
bool res = QObject::eventFilter(obj, event);
if (keyEvent->key() == Qt::Key_Return) {
return true; /* Always accept return */
} else {
return res;
}
} else {
// standard event processing
return QObject::eventFilter(obj, event);
}
}
И в вашем коде для каждого виджета в диалоге:
myWidget->installEventFilter(myKeyPressEater);
Если у вас в диалоговом окне есть обычные кнопки QPushButton, то если для кнопок заданы свойства autoDefault и / или по умолчанию, то вы получите кнопку по умолчанию — то, что вызывает клавиша ввода. В этом случае избавьтесь от autoDefault на кнопках, и нажатие клавиши ввода в другом виджете больше не закрывает диалоговое окно.
В случае QDialogButtonBox вы, вероятно, можете перебирать кнопки, чтобы отключить эту вещь в ctor вашего диалога. Не проверено здесь, но должно работать. Если нет, то вам также нужно посмотреть, есть ли кнопка по умолчанию, которая также устанавливается на самом QDialog.
Чтобы избежать закрытия кнопки «ОК» или «Ввод» из диалогового окна:
в пользовательском XML-файле удалите соединение / слот для принятия / отклонения. Затем в вашем коде emmit accept (), когда и когда это необходимо;
Пример из файла пользовательского интерфейса, который подключает слот accept ():
<connections>
<connection>
<sender>products_ButtonBox</sender>
<signal>accepted()</signal>
<receiver>Products_Dialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>e
</hints>
</connection>
В PySide (и я представляю себе PyQt) я смог переопределить функции принятия и отклонения QDialog.
def custom_accept ():
# perform custom actions when you hit open
pass
def custom_reject ():
# perform custom actions when you hit cancel
pass
file_dialog = QtGui.QFileDialog(directory=".")
file_dialog.accept = custom_accept
file_dialog.reject = custom_reject
Это препятствовало закрытию диалогового окна файла и давало мне доступ к данным, когда были запущены функции «ОК» (принять) или «Отмена» (отклонить) (либо нажатием клавиши «Ввод», либо нажатием кнопок).