Моя программа для Linux имеет имя, подобное MyProgram_0001, и более новые версии получают более высокие номера. При запуске приложение ищет более новую версию в том же каталоге, и, если оно находит, она вызывается с помощью execl (). Это прекрасно работает, но пока мышь продолжает работать, новая версия не получает никакого ввода с клавиатуры, даже если я предварительно нажму в ее окне. Вызывающее приложение исчезло, другие запущенные программы продолжают получать ввод с клавиатуры ... Есть идеи? На самом деле программа написана на C ++ Qt Designer 4.7, но это не должно быть важно, или, может быть, это так :-)?
ОК, еще немного информации ... Вот код, который ловит ключи и вызывает мои слоты ...
// define my own event handler
// capture all key presses ...
bool Layout10::eventFilter(QObject *obj, QEvent *event)
{
if (event->type() == QEvent::KeyPress)
{
QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
// directly exit on Alt-keys
if (keyEvent->modifiers()&Qt::AltModifier) return true;
// normal keyboard
if ((!(keyEvent->modifiers()&Qt::KeypadModifier))&&(Keyboard_On)) switch (keyEvent->key())
{
case Qt::Key_0: C->Num0ButtonClicked_KP(); return true;
case Qt::Key_1: C->Num1ButtonClicked_KP(); return true;
case Qt::Key_2: C->Num2ButtonClicked_KP(); return true;
case Qt::Key_3: C->Num3ButtonClicked_KP(); return true;
case Qt::Key_4: C->Num4ButtonClicked_KP(); return true;
case Qt::Key_5: C->Num5ButtonClicked_KP(); return true;
case Qt::Key_6: C->Num6ButtonClicked_KP(); return true;
case Qt::Key_7: C->Num7ButtonClicked_KP(); return true;
case Qt::Key_8: C->Num8ButtonClicked_KP(); return true;
case Qt::Key_9: C->Num9ButtonClicked_KP(); return true;
case Qt::Key_X: C->XButtonClicked_KP(); return true;
case Qt::Key_Backspace: C->EButtonClicked_KP(); return true;
case Qt::Key_F1: C->F1ButtonClicked_KP(); return true;
case Qt::Key_F2: C->F2ButtonClicked_KP(); return true;
case Qt::Key_F3: C->F3ButtonClicked_KP(); return true;
}
// keypad
if ((keyEvent->modifiers()&Qt::KeypadModifier)&&(Keypad_On)) switch (keyEvent->key())
{
case Qt::Key_0: C->Num0ButtonClicked_KP(); return true;
case Qt::Key_Insert: C->Num0ButtonClicked_KP(); return true;
case Qt::Key_1: C->Num1ButtonClicked_KP(); return true;
case Qt::Key_End: C->Num1ButtonClicked_KP(); return true;
case Qt::Key_2: C->Num2ButtonClicked_KP(); return true;
case Qt::Key_Down: C->Num2ButtonClicked_KP(); return true;
case Qt::Key_3: C->Num3ButtonClicked_KP(); return true;
case Qt::Key_PageDown: C->Num3ButtonClicked_KP(); return true;
case Qt::Key_4: C->Num4ButtonClicked_KP(); return true;
case Qt::Key_Left: C->Num4ButtonClicked_KP(); return true;
case Qt::Key_5: C->Num5ButtonClicked_KP(); return true;
case Qt::Key_Clear: C->Num5ButtonClicked_KP(); return true;
case Qt::Key_6: C->Num6ButtonClicked_KP(); return true;
case Qt::Key_Right: C->Num6ButtonClicked_KP(); return true;
case Qt::Key_7: C->Num7ButtonClicked_KP(); return true;
case Qt::Key_Home: C->Num7ButtonClicked_KP(); return true;
case Qt::Key_8: C->Num8ButtonClicked_KP(); return true;
case Qt::Key_Up: C->Num8ButtonClicked_KP(); return true;
case Qt::Key_9: C->Num9ButtonClicked_KP(); return true;
case Qt::Key_PageUp: C->Num9ButtonClicked_KP(); return true;
case Qt::Key_Back: C->XButtonClicked_KP(); return true; // maybe it should have been backslash ?
case Qt::Key_Delete: C->EButtonClicked_KP(); return true;
case Qt::Key_division: C->F1ButtonClicked_KP(); return true;
case Qt::Key_multiply: C->F2ButtonClicked_KP(); return true;
case Qt::Key_Minus: C->F3ButtonClicked_KP(); return true;
}
return true; // event is NOT given over for further processing
}
else
{
return false; // other events may be processed further
}
}
Keyboard_On
- это просто открытый логический член класса, который я использую для отключения клавиатуры, если пользователю предоставляется сенсорный экран. Приведенный выше обработчик сообщений устанавливается следующим образом ...
this->installEventFilter(this);
... в конструкторе класса виджетов ... У меня есть один такой обработчик для всех классов виджетов, которые составляют мои диалоги ... Ну, это работает, если я не запускаю приложение из себя через execl или startDetached()
...
Одна вещь попалась на глаза в описании startDetached()
... Они пишут, что новый процесс работает в собственной среде и ведет себя как демон в Linux. Интересно, вот почему я теряю ключи ...
Действительно, это озадачивает меня. Есть ли какая-то цепочка слоев, которые должны пройти нажатия клавиш, и способ, которым я мог бы это отладить и посмотреть, на каком уровне я их теряю? Спасибо!
Подробнее ... Я обнаружил, что не теряю клавиатуру, если я вызываю точно такой же двоичный файл через execl. Если я скопирую этот бинарный файл на другое имя и назову его ... клавиатура исчезнет. Это сводится к единственному изменению буквы в вызове execl, только во втором параметре, при прочих равных условиях ошибка все равно возникает ... Кажется, что есть некоторый контекст, который остается тем же, если путь + двоичный файл одинаковы, но в противном случае ключи отправляются в старый контекст, а файл, вызываемый через execl, запускается в другом контексте ...