《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

相关推荐
小白舒_SC27 分钟前
多个VS版本的Qt VS Tools的QtMsBuild不兼容问题
经验分享·qt
金色熊族7 小时前
QTransform使用心得(二)--仿射变换、非仿射变换、矩阵
qt·线性代数·矩阵
乌托邦2号11 小时前
Qt实现CS的自动化构建流程
qt·自动化
小短腿的代码世界12 小时前
WebSocket协议在Qt中的工业级实现:5层架构设计与万级并发压测验证
qt·websocket·网络协议
金色熊族14 小时前
Qt绘制图形时自定义点划线间隔的办法--setDashPattern
qt
小短腿的代码世界1 天前
Qt行情协议解析与二进制编解码优化:从FIX到自定义协议的全链路架构
开发语言·qt·架构
luoyayun3611 天前
Qt/QML + FFmpeg 实现多音频文件顺序拼接功能
qt·ffmpeg·音频拼接
Strugglingler1 天前
【Qt,OpenGL, RHI,Wayland 等概念梳理】
qt·opengl·wayland·rhi·x11·egl·glx
小短腿的代码世界1 天前
Qt对象树析构链与智能指针协同:零泄漏内存管理架构
开发语言·qt·架构
小庞在加油1 天前
从qmake到CMake+VSCode:Qt项目现代化迁移与AI提效实战指南
vscode·qt·ai·ai工具