ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Qt窗口置顶与激活

2021-12-31 02:06:02  阅读:426  来源: 互联网

标签:窗口 Qt 窗体 激活 changeEvent event 置顶


一、环境及问题

系统环境:windows10 64位企业版

开发环境:vs2017+qt5.9.9+vsaddin2.7.2.2

问题:qt界面程序主界面置顶,并一直获取焦点使qt主窗口一直处于激活状态。

思路:定时器或者相关事件重载。

二、置顶方法

通过函数setWindowFlags设置属性:Qt::WindowStaysOnTopHint即可(setWindowFlags(Qt::CustomizeWindowHint);//窗口位置为普通)。

具体设置方法:通过main函数主窗体对象调用。

例如:

w.setWindowFlags(Qt::WindowStaysOnTopHint);
查看代码

三、激活方法

3.1定时器方法

在程序运行主题部分设置定时器,然后启动定时器,构造连接槽使定时器和激活窗口的相关操作相关联。

本示例把定时器放在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();
}
查看代码

缺点:定时重复激活主窗口,即使不需要重新激活窗口也会重复激活,浪费计算资源。

3.2事件重载-休眠唤醒激活方法(推荐)

重载主窗体类的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,否则不能重新激活窗口。

3.3事件重载-重置窗口位置方法(推荐)

和上面方法类似,只是置顶使用函数不一样,样例如下(头文件不再赘述):

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
        }
    }
}
查看代码

3.4事件重载-最小化窗口然后重新显示

具体代码如下:

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
        }
    }
}
查看代码

标签:窗口,Qt,窗体,激活,changeEvent,event,置顶
来源: https://www.cnblogs.com/mehome/p/15751146.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有