《QDebug 2023年7月》

一、Qt Widgets 问题交流

1.QPainter旋转角度绘制线条的一点问题

QPainter 旋转角度,等距绘制若干线条,会出现绘制不均匀的情况:

但是在测试 QML Canvas 绘制时,发现效果是正常的,原来是因为 Canvas 默认的 capStyle 不一样,QPainter 设置成 FlatCap 后,绘制效果就正常了。

cpp 复制代码
void MyPaintedItem::paint(QPainter *painter)
{
    QRect rect = boundingRect().toRect();
    QPoint center = rect.center();

    painter->save();
    painter->translate(center.x(), center.y());
    painter->setRenderHint(QPainter::Antialiasing, true);

    int r = qMin(rect.width(), rect.height()) / 2 - 2;
    double line_width = 0.5; // + 1E-7;
    QPen pen;
    pen.setColor(QColor(127, 0, 0));
    pen.setWidthF(line_width);
    pen.setJoinStyle(Qt::MiterJoin);
    // QML Canvas 默认 flat, QPainter 默认 square
    // 如果不使用 flat,多次旋转后可能会不均匀
    // pen.setCapStyle(Qt::FlatCap);
    for (int i = 0; i < mLineCount; i++)
    {
        // 如果不使用 save/restore, 多次旋转后可能会不均匀
        painter->save();
        painter->rotate(mRotation + 360.0 / mLineCount * i);
        QPainterPath path;
        path.moveTo(0, 0);
        path.lineTo(r, 0);
        painter->strokePath(path, pen);
        painter->restore();
    }
    painter->restore();
}

二、Qt Quick 问题交流

1.QML Window 设置 WindowStaysOnTopHint 置顶后,窗口标题栏没了

测试环境 Win11 + Qt5.15.2

QML 设置 WindowStaysOnTopHint 置顶后,窗口标题栏没了,但是 QWidget 显示正常

cpp 复制代码
flags: Qt.Window|Qt.WindowStaysOnTopHint

需要把标题栏和按钮的 Hint 全部加上才能显示:

cpp 复制代码
flags: Qt.Window|Qt.WindowStaysOnTopHint|Qt.WindowTitleHint|
       Qt.WindowSystemMenuHint|Qt.WindowMinMaxButtonsHint|
       Qt.WindowCloseButtonHint|Qt.WindowFullscreenButtonHint

也可以参考网友的代码,获取窗口 id 后用 Win32 接口切换置顶状态:

https://blog.csdn.net/qq_34719188/article/details/131689748

三、其他

1.Qt5 QSysInfo 在 Win11 上获取的系统信息为 Win10

因为 Win11 需要从 OSVERSIONINFOEX 结构体的 dwBuildNumber 字段来判断,dwBuildNumber ≥ 22000 时判定为 Win11,而 dwMajorVersion 在 Win10 和 Win11 都是 10。

参考 Qt6.5 代码:

cpp 复制代码
static inline OSVERSIONINFOEX determineWinOsVersion()
{
    OSVERSIONINFOEX result = { sizeof(OSVERSIONINFOEX), 0, 0, 0, 0, {'\0'}, 0, 0, 0, 0, 0};

    HMODULE ntdll = GetModuleHandleW(L"ntdll.dll");
    if (Q_UNLIKELY(!ntdll))
        return result;

    typedef NTSTATUS (NTAPI *RtlGetVersionFunction)(LPOSVERSIONINFO);

    // RtlGetVersion is documented public API but we must load it dynamically
    // because linking to it at load time will not pass the Windows App Certification Kit
    // https://msdn.microsoft.com/en-us/library/windows/hardware/ff561910.aspx
    RtlGetVersionFunction pRtlGetVersion = reinterpret_cast<RtlGetVersionFunction>(
        reinterpret_cast<QFunctionPointer>(GetProcAddress(ntdll, "RtlGetVersion")));
    if (Q_UNLIKELY(!pRtlGetVersion))
        return result;

    // GetVersionEx() has been deprecated in Windows 8.1 and will return
    // only Windows 8 from that version on, so use the kernel API function.
    pRtlGetVersion(reinterpret_cast<LPOSVERSIONINFO>(&result)); // always returns STATUS_SUCCESS
    return result;
}

OSVERSIONINFOEX qWindowsVersionInfo()
{
    OSVERSIONINFOEX realResult = determineWinOsVersion();
#ifdef QT_DEBUG
    // ... ...
#endif
    return realResult;
}

static const char *osVer_helper(QOperatingSystemVersion version = QOperatingSystemVersion::current())
{
    Q_UNUSED(version);
    const OSVERSIONINFOEX osver = qWindowsVersionInfo();
    const bool workstation = osver.wProductType == VER_NT_WORKSTATION;

#define Q_WINVER(major, minor) (major << 8 | minor)
    switch (Q_WINVER(osver.dwMajorVersion, osver.dwMinorVersion)) {
    case Q_WINVER(10, 0):
        if (workstation) {
            if (osver.dwBuildNumber >= 22000)
                return "11";
            return "10";
        }
        // else: Server
        if (osver.dwBuildNumber >= 20348)
            return "Server 2022";
        if (osver.dwBuildNumber >= 17763)
            return "Server 2019";
        return "Server 2016";
    }
#undef Q_WINVER
    // unknown, future version
    return nullptr;
}

2.32位程序虚拟地址空间大小

遇到32位程序程序在占用1.5G左右内存溢出崩掉的问题,应该是实际的虚拟地址可用的不足2GB,即使设置了启用大地址接近 4GB 和 1.5 GB 差别也不大,数据量较大的时候还是会溢出。

cpp 复制代码
QMAKE_LFLAGS_WINDOWS += /LARGEADDRESSAWARE

Windows文档:https://learn.microsoft.com/en-us/windows-hardware/drivers/gettingstarted/virtual-address-spaces

相关推荐
小短腿的代码世界9 小时前
Qt Bluetooth源码深度解析:从HCI协议到跨平台API的完整架构
开发语言·qt·架构
小短腿的代码世界10 小时前
Qt WebEngine多进程架构与IPC通信:从Chromium多进程到Qt信号槽融合
qt·架构·系统架构
尘中远11 小时前
【Qwt 7.0 系列】快速入门与核心新特性概览 —— 更现代的 Qt 数据可视化库
qt·数据可视化·绘图·qwt·科学绘图
初阳78513 小时前
【Qt】系统相关(3)——多线程
qt
初阳78516 小时前
【Qt】系统相关(2)——文件
开发语言·qt
尘中远1 天前
【Qwt 7.0 系列】坐标轴与刻度系统 —— 刻度引擎、网格、图例与刻度朝内
qt·数据可视化·qcustomplot·qwt·工业软件·科学绘图
sycmancia1 天前
Qt——多线程间的互斥
开发语言·qt
尘中远2 天前
【Qwt 7.0 系列】常用图表类型实战 —— 柱状图、散点图、箱线图与直方图
qt·qwt·工业软件·科学绘图
尘中远2 天前
【Qwt 7.0 系列】交互功能详解 —— 平移、缩放、坐标轴交互与数据拾取
qt·数据可视化·绘图·qcustomplot·qwt·科学绘图
sycmancia2 天前
Qt——进程与线程的概念
qt