系统环境:windows10 64位企业版
开发环境:vs2017+qt5.9.9+vsaddin2.7.2.2
问题:qt界面程序主界面置顶,并一直获取焦点使qt主窗口一直处于激活状态。
思路:定时器或者相关事件重载。
通过函数setWindowFlags设置属性:Qt::WindowStaysOnTopHint即可(setWindowFlags(Qt::CustomizeWindowHint);//窗口位置为普通)。
具体设置方法:通过main函数主窗体对象调用。
例如:
w.setWindowFlags(Qt::WindowStaysOnTopHint);查看代码
在程序运行主题部分设置定时器,然后启动定时器,构造连接槽使定时器和激活窗口的相关操作相关联。
本示例把定时器放在qt程序的main函数内部,具体main函数如下:
#include <QtWidgets/QApplication> #include <QTimer> int main(int argc, char *argv[]) { QApplication a(argc, argv); GetMouseRGB w; w.setWindowFlags(Qt::WindowStaysOnTopHint); w.show(); QTimer *t = new QTimer; /* 定时两秒 */ t->start(200); QObject::connect(t, &QTimer::timeout, [&w]() { /* 提升该窗口到父窗口堆栈的顶部 */ w.raise(); /* 显示窗口 */ w.show(); /* 激活窗口 */ w.activateWindow(); }); return a.exec(); }查看代码
缺点:定时重复激活主窗口,即使不需要重新激活窗口也会重复激活,浪费计算资源。
重载主窗体类的changeEvent函数,然后在这个重载函数内部激活qt窗口。
主窗体头文件(*.h)需要添加重载声明,如下:
protected: //重载事件 void changeEvent(QEvent *event);查看代码
主窗体实现文件(*.cpp)需要添加相应实现,如下:
void GetMouseRGB::changeEvent(QEvent *event) { QWidget::changeEvent(event); if (event->type() == QEvent::ActivationChange) { if (this->isActiveWindow()) { // widget is now active return; } else { //休眠10毫秒 QThread::msleep(10); //主窗体显示堆栈置顶 this->raise(); //显示窗体 this->show(); //激活主窗体 this->activateWindow(); // widget is now inactive } } }查看代码
注意:changeEvent重载函数激活窗口前需要msleep,否则不能重新激活窗口。
和上面方法类似,只是置顶使用函数不一样,样例如下(头文件不再赘述):
void GetMouseRGB::changeEvent(QEvent *event) { QWidget::changeEvent(event); if (event->type() == QEvent::ActivationChange) { if (this->isActiveWindow()) { // widget is now active return; } else { setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint); ::SetWindowPos((HWND)winId(), HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); ////休眠10毫秒 //QThread::msleep(10); ////主窗体显示堆栈置顶 //this->raise(); ////显示窗体 //this->show(); ////激活主窗体 //this->activateWindow(); //// widget is now inactive } } }查看代码
具体代码如下:
void GetMouseRGB::changeEvent(QEvent *event) { QWidget::changeEvent(event); if (event->type() == QEvent::ActivationChange) { if (this->isActiveWindow()) { // widget is now active return; } else { activateWindow(); setWindowState((windowState() & ~Qt::WindowMinimized) | Qt::WindowActive); raise();//必须加,不然X11会不起作用 #ifdef Q_OS_WIN32 //windows必须加这个,不然windows10 会不起作用,具体参看activateWindow 函数的文档 HWND hForgroundWnd = GetForegroundWindow(); DWORD dwForeID = ::GetWindowThreadProcessId(hForgroundWnd, NULL); DWORD dwCurID = ::GetCurrentThreadId(); ::AttachThreadInput(dwCurID, dwForeID, TRUE); ::SetForegroundWindow((HWND)winId()); ::AttachThreadInput(dwCurID, dwForeID, FALSE); #endif // MAC_OS //setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint); //::SetWindowPos((HWND)winId(), HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); ////休眠10毫秒 //QThread::msleep(10); ////主窗体显示堆栈置顶 //this->raise(); ////显示窗体 //this->show(); ////激活主窗体 //this->activateWindow(); //// widget is now inactive } } }查看代码