QT事件机制详解

导读

  • 窗体的创建过程
  • 事件的类型和产生
    • 系统事件(消息)
    • 程序事件
  • 事件的循环和传播
  • 事件的处理

窗体的创建过程

首先推荐一个网站(https://code.woboq.org/),可以直接看QT所有类的源码,想看什么直接在里面搜索就可以看到,非常好用且方便;比如想QWidget的源码,就在网站里搜索QWidget,然后选择qwidget.cpp,就可以看到QWidget的源码实现,下面所贴的源码都是在这个网站上copy来的。

1. 首先进入main方法后,经过层层调用,最终会调用 QWidgetPrivate::create_sys ()方法,中间的调用层次我已省略,有兴趣的可以自己去看看,在生成窗口的同时,系统会为这个窗口生成并维护一个消息队列

int main(int argc, char *argv[])
{
   
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();
}
//...经过多层调用后会进入下面这个函数,中间的调用层次我已省略,有兴趣的可以自己去看看
void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyOldWindow)
{
   
	//...为了方便观察,我把一些代码删掉了,看下面的关键代码就行
    QString windowClassName = qt_reg_winclass(q); //qt_reg_winclass方法在下面贴出
    if (!window)                                // always initialize
        initializeWindow = true;
    if (popup)
        flags |= Qt::WindowStaysOnTopHint; // a popup stays on top
        
   //...删除了中间代码,这些代码主要是设置一些窗口的相关flags、style
    if (!topLevel && q->testAttribute(Qt::WA_NativeWindow) && q->testAttribute(Qt::WA_Mapped)) {
   
        Q_ASSERT(q->internalWinId());
        ShowWindow(q->internalWinId(), SW_SHOW); //到此就创建完了一个窗口
    }
}

2. 下面来看窗体注册函数qt_reg_winclass(QWidget *),这个函数的主要作用就是调用windows api,进行窗口的注册,让系统生成一个窗口;wc.lpfnWndProc = (WNDPROC)QtWndProc;这一行代码是重点,把QtWndProc注册到系统;QtWndProc是系统消息处理回调函数,系统处理完消息后会调用这个函数,这个函数里再对系统处理过的消息进行分类处理

const QString qt_reg_winclass(QWidget *w)
{
   
//...省略代码
#ifndef Q_WS_WINCE
    WNDCLASSEX wc;
    wc.cbSize       = sizeof(WNDCLASSEX);
#else
    WNDCLASS wc;
#endif
    wc.style        = style;
    wc.lpfnWndProc  = (WNDPROC)QtWndProc; //重点:把消息处理回调函数注册到系统
    wc.cbClsExtra   = 0;
    wc.cbWndExtra   = 0;
    wc.hInstance    = qWinAppInst();
    if (icon) {
   
        wc.hIcon = (HICON)LoadImage(qWinAppInst(), L"IDI_ICON1", IMAGE_ICON, 0, 0, LR_DEFAULTSIZE);
#ifndef Q_WS_WINCE
        if (wc.hIcon) {
   
            int sw = GetSystemMetrics(SM_CXSMICON);
            int sh = GetSystemMetrics(SM_CYSMICON);
            wc.hIconSm = (HICON)LoadImage(qWinAppInst(), L"IDI_ICON1", IMAGE_ICON, sw, sh, 0);
        } else {
   
            wc.hIcon = (HICON)LoadImage(0, IDI_APPLICATION, IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_SHARED);
            wc.hIconSm = 0;
        }
#endif
    } else {
   
        wc.hIcon    = 0;
#ifndef Q_WS_WINCE
        wc.hIconSm  = 0;
#endif
    }
    wc.hCursor      = 0;
#ifndef Q_WS_WINCE
    HBRUSH brush = 0;
    if (w && !qt_widget_private

你可能感兴趣的:(qt)