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;
}
相关推荐
代钦塔拉6 小时前
Qt4 vs Qt5 带参数信号槽的连接方式详解
开发语言·数据库·qt
不午休の野猫8 小时前
vs + qt环境编译.sln项目时报无法解析的外部符号metaObject && qt_metacast
开发语言·qt
牵牛老人14 小时前
CAN通讯实战:Qt基于周立功 USBCAN 的 CAN 总线通信开发全攻略
网络·qt·系统架构
_君莫笑15 小时前
Qt+Qml前后端分离上位机软件技术方案
c++·qt·用户界面·qml
想取一个与众不同的名字好难16 小时前
QT webSocket接收客户端发送的双目摄像头数据并显示
开发语言·qt·websocket
基德爆肝c语言16 小时前
Qt控件:按钮类
开发语言·qt
基德爆肝c语言19 小时前
Qt:显示类控件
开发语言·qt·命令模式
小许同学记录成长20 小时前
基于 QxOrm 的 Qt 持久化层技术指南
开发语言·数据库·qt
辞旧 lekkk1 天前
【Qt】信号和槽
linux·开发语言·数据库·qt·学习·mysql·萌新
liuhuizuikeai1 天前
可视化门禁---Linux/Qt+SqLite篇
linux·运维·qt