Qt Creator源码分析系列——utils/appmainwindow

AppMainWindow继承自QMainWindow类(#include <QMainWindow>),

class QTCREATOR_UTILS_EXPORT AppMainWindow : public QMainWindow
{
    Q_OBJECT
public:
    AppMainWindow();
public slots:
    void raiseWindow();
signals:
    void deviceChange();
#ifdef Q_OS_WIN
protected:
    virtual bool winEvent(MSG *message, long *result);
    bool event(QEvent *event) override;
#endif
private:
    const int m_deviceEventId;
};

通过使用自定义事件延迟通知信号,否则将无法正确检测到设备删除(注册表中仍存在设备)。

class DeviceNotifyEvent : public QEvent {
public:
    explicit DeviceNotifyEvent(int id) : QEvent(static_cast<QEvent::Type>(id)) {}
};
AppMainWindow::AppMainWindow() : m_deviceEventId(QEvent::registerEventType(QEvent::User + 2)) { }

在这里插入图片描述
注册并返回自定义事件类型。如果hint没有被使用则使用它,否则将返回QEvent :: User和QEvent :: MaxUser之间尚未注册的值。 如果hint值不在QEvent :: User和QEvent :: MaxUser之间,则忽略该提示。如果所有可用值都已被使用或程序正在关闭,则返回-1。此函数是线程安全的。
此功能在Qt 4.4中引入。

void AppMainWindow::raiseWindow()
{
    setWindowState(windowState() & ~Qt::WindowMinimized);
    raise();
    activateWindow();
}

在这里插入图片描述
返回当前窗口状态。一般是一组状态的或值( Qt::WindowMinimized, Qt::WindowMaximized, Qt::WindowFullScreen, Qt::WindowActive.)
在这里插入图片描述
将此小部件提升到父小部件堆栈的顶部。在此调用之后,该小部件将在视觉上位于任何重叠的同级小部件之前。
注意:使用activateWindow()时,可以调用此函数以确保窗口堆叠在顶部。
在这里插入图片描述
将包含此窗口部件的顶级窗口部件设置为活动窗口。活动窗口是具有键盘输入焦点的可见顶级窗口。
该功能执行与在顶级窗口的标题栏上单击鼠标相同的操作。 在X11上,结果取决于Window Manager。 如果要确保窗口也堆叠在顶部,则还应该调用raise()。 请注意,该窗口必须可见,否则activateWindow()无效。在Windows上,如果您在应用程序当前不是活动的应用程序时调用它,则它将不会使其成为活动的窗口。 它将更改任务栏条目的颜色,以指示窗口已经过某种更改。 这是因为Microsoft不允许应用程序中断用户在另一个应用程序中当前正在执行的操作。

event事件和winEvent事件处理,如果事件类型等于自定义事件类型,就accept这个事件,并发射自定义的信号deviceChange。如果是QEvent::ThemeChange,就调用setThemeApplicationPalette()。winEvent事件处理和window上回调函数WindowProc类似。winEvent事件是虚函数。

#ifdef Q_OS_WIN
bool AppMainWindow::event(QEvent *event)
{
    const QEvent::Type type = event->type();
    if (type == m_deviceEventId) {
        event->accept();
        emit deviceChange();
        return true;
    }
    if (type == QEvent::ThemeChange)
        setThemeApplicationPalette();
    return QMainWindow::event(event);
}
bool AppMainWindow::winEvent(MSG *msg, long *result)
{
    if (msg->message == WM_DEVICECHANGE) {
        if (msg->wParam & 0x7 /* DBT_DEVNODES_CHANGED */) {
            *result = TRUE;
            QCoreApplication::postEvent(this, new DeviceNotifyEvent(m_deviceEventId));
        }
    }
    return false;
}
#endif

QCoreApplication::postEvent(this, new DeviceNotifyEvent(m_deviceEventId)) 就是将AppMainWindow作为DeviceNotifyEvent事件的接收者,并将该event事件添加到事件队列中。
在这里插入图片描述
将对象接收者receiver作为事件event的接收者,并将该event事件添加到事件队列中并立即返回。该事件必须在堆上分配,因为发布事件队列将拥有该事件的所有权,并在发布后将其删除。 发布事件后,访问该事件是不安全的。
当控制权返回主事件循环时,将使用notify()函数发送队列中存储的所有事件。
事件按优先级从高到低的顺序排序,即优先级高的事件在优先级较低的事件之前排队。 优先级可以是任何整数值,即介于INT_MAX和INT_MIN之间(包括两端); 有关更多详细信息,请参见Qt :: EventPriority。 具有相同优先级的事件将按照发布的顺序进行处理。注意:此函数是线程安全的。此功能在Qt 4.3中引入。

发布了134 篇原创文章 · 获赞 141 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/asmartkiller/article/details/104437167