我的Linux程序的名称类似于MyProgram_0001,较新版本的数字更高。启动时,应用程序在同一目录中查找较新版本,如果找到,则通过execl()调用它。这很好用,但是当鼠标继续工作时,即使我事先在其窗口中单击,新版本也不会获得任何键盘输入。调用应用程序已经消失,其他正在运行的程序继续获得键盘输入...任何想法?实际上该程序是用C ++ Qt Designer 4.7应用程序编写的,但这应该不重要,或者可能是:-)?
好的,还有更多信息......这是捕获密钥并调用我的SLOT的代码......
// 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);
...在widget类的构造函数中...我有一个这样的处理程序用于构成我的对话框的所有窗口小部件......嗯,除非我通过execl或{{从它自己启动应用程序,否则它是有效的1}} ...
有一件事引起了我对startDetached()
的描述的注意......他们写道,新进程在自己的环境中运行,行为就像Linux下的守护进程。我想知道这是不是我放松钥匙的原因......
真的这让我很困惑。键盘必须通过一些层链,还有一种方法可以调试,看看我放松了什么级别?谢谢!
更多信息...如果我通过execl调用完全相同的二进制文件,我发现我没有松开键盘。如果我将该二进制文件复制到另一个名称并调用它...键盘就不见了。它归结为execl调用中的单个字母更改,仅在第二个参数中,所有其他相同的错误仍然发生...似乎有一些上下文如果路径+二进制相同,则保持不变,但是否则密钥被发送到旧的上下文,通过execl调用的文件在不同的上下文中启动...
答案 0 :(得分:0)
许多应用程序通过以运行二进制文件的shell脚本而不是二进制文件本身来处理此类问题。 Firefox就是这么做的。您可以在脚本中执行“最新版本”检查。
答案 1 :(得分:0)
我很好奇:你在致电execl
之前是否进行了任何清理工作?你是在Qt事件循环中调用它还是先退出它?
execve(2)
函数(execl(3)
is a wrapper of)执行了多种interesting stuff,其中包含调用过程的状态,我对此印象深刻,甚至可以在以后工作:
execve()在成功时不返回,并且调用进程的text,data,bss和stack将被加载的程序覆盖。调用的程序继承了调用进程的PID,以及未设置为在exec上关闭的任何打开的文件描述符。将清除呼叫进程中待处理的信号。设置为由调用进程捕获的任何信号都将重置为其默认行为。 SIGCHLD信号(设置为SIG_IGN时)可能会也可能不会重置为SIG_DFL。
其中一些可能会破坏Qt或X服务器状态的内部或其他完全。对于Qt来说,一切似乎都是从头开始。对于其他人来说,这是一个相同的过程。
如果在“切换”之前清理所有内容,为什么要重复使用相同的过程?请改用QProcess::startDetached()
。
编辑。您的上一句话是无条件阻止按键。如果仅当Keyboard_On或Keypad_On为真时才应锁定键盘,则最后一条语句:
return true; // event is NOT given over for further processing
实际应该是return false
。您只会在应用重新启动时注意到这一点,因为可能只有较新版本的应用会丢弃关键事件。