《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

相关推荐
Quz3 小时前
QML 拖拽篇:接收拖拽与数据交换
qt
张人玉21 小时前
基于 Python 机器学习 与 PyQt5 桌面框架开发的可视化分析系统——基于大数据的网上购物消费行为分析可视化大屏
python·qt·机器学习·echarts·three.js
「QT(C++)开发工程师」21 小时前
C++11 std::unique_ptr — 独占所有权的智能指针
c语言·开发语言·c++·qt
小镇敲码人1 天前
【深入浅出】之Qt 事件系统实战:鼠标、键盘、滚轮、窗口与定时器事件
数据库·qt·网络协议·mysql·http
小小龙学IT1 天前
Qt 数据库编程(Qt SQL 模块)深度解析
数据库·sql·qt
Qt历险记1 天前
C++11 std::unique_ptr — 独占所有权的智能指针
qt
宏笋1 天前
一款集结古今中外文学查阅与编辑的软件
qt
机器视觉知识推荐、就业指导2 天前
为什么老说“纯 Qt 没啥就业市场”?
开发语言·qt
telepan2 天前
Qt 开发避坑与性能指南:如何优雅、安全地定义全局常量字符串?
开发语言·qt
小灰灰搞电子2 天前
完全驾驭 Qt 与数据库:C++ ORM 框架 QxOrm 原理与实践指南
数据库·c++·qt