其他分享
首页 > 其他分享> > Qt窗口置顶与激活

Qt窗口置顶与激活

作者:互联网

一、环境及问题

系统环境: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