《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

相关推荐
StrokeAce1 小时前
linux桌面软件(wps)内嵌到主窗口后的关闭问题
linux·c++·qt·wps·窗口内嵌
威桑9 小时前
记一次控件提升后,运行却不显示的Bug
qt
FL162386312910 小时前
[深度学习][python]yolov11+bytetrack+pyqt5实现目标追踪
深度学习·qt·yolo
优雅的小武先生15 小时前
QT中的按钮控件和comboBox控件和spinBox控件无法点击的bug
开发语言·qt·bug
Death20015 小时前
使用Qt进行TCP和UDP网络编程
网络·c++·qt·tcp/ip
海绵波波10717 小时前
Qt操作主/从视图及XML——实例:汽车管理系统
xml·qt·汽车
Fairy_sevenseven17 小时前
【二十八】【QT开发应用】模拟WPS Tab
开发语言·qt·wps
Death20017 小时前
Qt 中的 QListWidget、QTreeWidget 和 QTableWidget:简化的数据展示控件
c语言·开发语言·c++·qt·c#
niu_sama17 小时前
基于muduo库函数实现protobuf协议的通信
开发语言·qt
不写八个18 小时前
Qt教程(001):Qt概述与安装
开发语言·qt