Qt之Gui

组件依赖关系

应用

QGuiApplication QApplication QCoreApplication

QApplication:widget对应的应用

QGuiApplication :gui对应的应用

QCoreApplication :无gui对应的应用

widget

QWidget QMainWindow QWidgetWindow QWindow QPlatformIntegration QPlatformWindow

QPlatformIntegration:平台抽象

QPlatformWindow :平台 抽象窗口

windows平台

QPlatformIntegration QWindowsIntegration QPlatformWindow QWindowsBaseWindow QWindowsWindow QWindowsDesktopWindow QWindowsForeignWindow QWindowsContext

在QWindowsIntegration创建createPlatformWindow时,其先创建QWindowsWindowData::create

cpp 复制代码
QWindowsWindowData
    WindowCreationData::create(const QWindow *w, const WindowData &data, QString title) const
{
    WindowData result;
    result.flags = flags;

    const auto appinst = reinterpret_cast<HINSTANCE>(GetModuleHandle(nullptr));

    const QString windowClassName = QWindowsContext::instance()->registerWindowClass(w);

    const QScreen *screen{};
    const QRect rect = QPlatformWindow::initialGeometry(w, data.geometry,
                                                        defaultWindowWidth, defaultWindowHeight,
                                                        &screen);

    if (title.isEmpty() && (result.flags & Qt::WindowTitleHint))
        title = topLevel ? qAppName() : w->objectName();

    const auto *titleUtf16 = reinterpret_cast<const wchar_t *>(title.utf16());
    const auto *classNameUtf16 = reinterpret_cast<const wchar_t *>(windowClassName.utf16());

    // Capture events before CreateWindowEx() returns. The context is cleared in
    // the QWindowsWindow constructor.
    const QWindowCreationContextPtr context(new QWindowCreationContext(w, screen, data.geometry,
                                                                       rect, data.customMargins,
                                                                       style, exStyle));
    QWindowsContext::instance()->setWindowCreationContext(context);

    const bool hasFrame = (style & (WS_DLGFRAME | WS_THICKFRAME));
    QMargins invMargins = topLevel && hasFrame && QWindowsGeometryHint::positionIncludesFrame(w)
            ? invisibleMargins(QPoint(context->frameX, context->frameY)) : QMargins();

    qCDebug(lcQpaWindows).nospace()
        << "CreateWindowEx: " << w << " class=" << windowClassName << " title=" << title
        << '\n' << *this << "\nrequested: " << rect << ": "
        << context->frameWidth << 'x' <<  context->frameHeight
        << '+' << context->frameX << '+' << context->frameY
        << " custom margins: " << context->customMargins
        << " invisible margins: " << invMargins;


    QPoint pos = calcPosition(w, context, invMargins);

    // Mirror the position when creating on a parent in RTL mode, ditto for the obtained geometry.
    int mirrorParentWidth = 0;
    if (!w->isTopLevel() && QWindowsBaseWindow::isRtlLayout(parentHandle)) {
        RECT rect;
        GetClientRect(parentHandle, &rect);
        mirrorParentWidth = rect.right;
    }
    if (mirrorParentWidth != 0 && pos.x() != CW_USEDEFAULT && context->frameWidth != CW_USEDEFAULT)
        pos.setX(mirrorParentWidth - context->frameWidth - pos.x());

    result.hwnd = CreateWindowEx(exStyle, classNameUtf16, titleUtf16,
                                 style,
                                 pos.x(), pos.y(),
                                 context->frameWidth, context->frameHeight,
                                 parentHandle, nullptr, appinst, nullptr);
    qCDebug(lcQpaWindows).nospace()
        << "CreateWindowEx: returns " << w << ' ' << result.hwnd << " obtained geometry: "
        << context->obtainedPos << context->obtainedSize << ' ' << context->margins;

    if (!result.hwnd) {
        qErrnoWarning("%s: CreateWindowEx failed", __FUNCTION__);
        return result;
    }

    if (mirrorParentWidth != 0) {
        context->obtainedPos.setX(mirrorParentWidth - context->obtainedSize.width()
                                  -  context->obtainedPos.x());
    }

    QRect obtainedGeometry(context->obtainedPos, context->obtainedSize);

    result.geometry = obtainedGeometry;
    result.fullFrameMargins = context->margins;
    result.embedded = embedded;
    result.hasFrame = hasFrame;
    result.customMargins = context->customMargins;

    return result;
}

内部会先注册registerWindowClass,设置窗口的处理函数registerWindowClass(cname, qWindowsWndProc, style, GetSysColorBrush(COLOR_WINDOW), icon);

qWindowsWndProc处理函数主要是调用 QWindowsContext的windowsProc

cpp 复制代码
QString QWindowsContext::registerWindowClass(QString cname,
                                             WNDPROC proc,
                                             unsigned style,
                                             HBRUSH brush,
                                             bool icon)
{
    // since multiple Qt versions can be used in one process
    // each one has to have window class names with a unique name
    // The first instance gets the unmodified name; if the class
    // has already been registered by another instance of Qt then
    // add a UUID. The check needs to be performed for each name
    // in case new message windows are added (QTBUG-81347).
    const auto appInstance = static_cast<HINSTANCE>(GetModuleHandle(nullptr));
    WNDCLASS wcinfo;
    const bool classExists = GetClassInfo(appInstance, reinterpret_cast<LPCWSTR>(cname.utf16()), &wcinfo) == TRUE
        && wcinfo.lpfnWndProc != proc;

    if (classExists)
        cname += QUuid::createUuid().toString();

    if (d->m_registeredWindowClassNames.contains(cname))        // already registered in our list
        return cname;

    WNDCLASSEX wc;
    wc.cbSize       = sizeof(WNDCLASSEX);
    wc.style        = style;
    wc.lpfnWndProc  = proc;
    wc.cbClsExtra   = 0;
    wc.cbWndExtra   = 0;
    wc.hInstance    = appInstance;
    wc.hCursor      = nullptr;
    wc.hbrBackground = brush;
    if (icon) {
        wc.hIcon = static_cast<HICON>(LoadImage(appInstance, L"IDI_ICON1", IMAGE_ICON, 0, 0, LR_DEFAULTSIZE));
        if (wc.hIcon) {
            int sw = GetSystemMetrics(SM_CXSMICON);
            int sh = GetSystemMetrics(SM_CYSMICON);
            wc.hIconSm = static_cast<HICON>(LoadImage(appInstance, L"IDI_ICON1", IMAGE_ICON, sw, sh, 0));
        } else {
            wc.hIcon = static_cast<HICON>(LoadImage(nullptr, IDI_APPLICATION, IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_SHARED));
            wc.hIconSm = nullptr;
        }
    } else {
        wc.hIcon    = nullptr;
        wc.hIconSm  = nullptr;
    }

    wc.lpszMenuName  = nullptr;
    wc.lpszClassName = reinterpret_cast<LPCWSTR>(cname.utf16());
    ATOM atom = RegisterClassEx(&wc);
    if (!atom)
        qErrnoWarning("QApplication::regClass: Registering window class '%s' failed.",
                      qPrintable(cname));

    d->m_registeredWindowClassNames.insert(cname);
    qCDebug(lcQpaWindows).nospace() << __FUNCTION__ << ' ' << cname
        << " style=0x" << Qt::hex << style << Qt::dec
        << " brush=" << brush << " icon=" << icon << " atom=" << atom;
    return cname;
}
相关推荐
Black_Friend28 分钟前
关于在VS中使用Qt不同版本报错的问题
开发语言·qt
CSUC36 分钟前
【Qt】QTreeView 和 QStandardItemModel的关系
qt
冷凝女子1 小时前
【QT】海康视频及openCv抓拍正脸接口
qt·opencv·音视频·海康
苏三有春4 小时前
PyQt5实战——UTF-8编码器功能的实现(六)
开发语言·qt
Vanranrr4 小时前
C++ QT
java·c++·qt
兆。4 小时前
掌握 PyQt5:从零开始的桌面应用开发
开发语言·爬虫·python·qt
徒步僧15 小时前
ThingsBoard规则链节点:RPC Call Reply节点详解
qt·microsoft·rpc
可峰科技16 小时前
斗破QT编程入门系列之一:认识Qt:初步使用(四星斗师)
开发语言·qt
我喜欢就喜欢16 小时前
基于qt vs下的视频播放
开发语言·qt·音视频
CP-DD17 小时前
Qt的架构设计
qt