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中引入。