Как я могу запретить клавише ввода закрывать мой QDialog (Qt 4.8.1)

у меня есть QDialog с QDialogButtonBox, Хорошо а также отменить кнопки активны. Иногда я отключаю или скрываю кнопку ОК в зависимости от состояния моего диалога. Кажется, что бы я ни делал, клавиша Enter всегда активирует кнопку ОК. Я действительно не хочу, чтобы это случилось. Я пытался:

  • Установка свойств по умолчанию и autoDefault на false каждый раз, когда я показываю / скрываю / включаю / отключаю / любую кнопку
  • установка фильтра событий на кнопку ОК для перехвата ключевых событий (нажата и отпущена) для возврата, ввода и пробела
  • Настройка политики фокусировки на кнопке NoFocus

И со всеми комбинациями этих вещей, указанных выше, клавиша Enter по-прежнему принимает диалог. Кто-нибудь знает, как это заблокировать? Кажется, я должен быть в состоянии заблокировать что-то столь же простое, как это?

10

Решение

Фильтрация событий нажатия клавиши должна выполняться в самом диалоге, потому что код, обрабатывающий пересылку 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;
}
8

Другие решения

QDialog имеет закрытый слот, который называется accept(), Всякий раз, когда QDialogButtonBox испускает accepted() (нажав клавишу возврата или нажав Ok), этот частный слот вызывается. Поэтому попробуйте отключить их.

disconnect(ui->buttonBox, SIGNAL(accepted()), this, SLOT(accept()));

Это сработало для меня.

1

Проблема в том, что фильтр событий не должен быть установлен на кнопку ОК.

Если ваша кнопка ОК отключена, то она не будет получать событие ввода. Какой бы виджет не был в фокусе, будет. И если они не принимают событие ввода, то 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);
1

Если у вас в диалоговом окне есть обычные кнопки QPushButton, то если для кнопок заданы свойства autoDefault и / или по умолчанию, то вы получите кнопку по умолчанию — то, что вызывает клавиша ввода. В этом случае избавьтесь от autoDefault на кнопках, и нажатие клавиши ввода в другом виджете больше не закрывает диалоговое окно.

В случае QDialogButtonBox вы, вероятно, можете перебирать кнопки, чтобы отключить эту вещь в ctor вашего диалога. Не проверено здесь, но должно работать. Если нет, то вам также нужно посмотреть, есть ли кнопка по умолчанию, которая также устанавливается на самом QDialog.

1

Чтобы избежать закрытия кнопки «ОК» или «Ввод» из диалогового окна:
в пользовательском 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>
0

В 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

Это препятствовало закрытию диалогового окна файла и давало мне доступ к данным, когда были запущены функции «ОК» (принять) или «Отмена» (отклонить) (либо нажатием клавиши «Ввод», либо нажатием кнопок).

-1