Qt程序匹配Windows字體縮放


問題

Windows系統提供了字體縮放功能,當字體縮放比率變大時,應用程序也需要做相應的調整來匹配顯示結果。
Qt提供了一個熟悉來設置是否自動縮放。

QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

但在啟用這個屬性后,只能是整數倍的縮放,比如125%是1倍,150%是2倍。這種效果是不能滿足需求的。

解決方案

可以使用Windows提供的方法GetDeviceCaps來計算字體的縮放比率,然后通過設置環境變量QT_SCALE_FACTOR來設置任意大小的縮放比率,這種方式可以提供double類型的縮放。
GetDeviceCaps需要在QApplication創建之后才能使用。這就需要首先啟動一次程序,獲取縮放比率,然后和當前程序設置的縮放比率進行對比,如果相同則繼續執行,否則就將縮放比率寫入注冊表中,重啟程序,在程序啟動時首先從注冊表中讀取縮放比率並設置到環境變量中,然后再創建QApplication。之后繼續判斷系統的縮放比率和程序設置的縮放比率是否相同。
代碼如下

#include "mainwindow.h"
#include <QApplication>
#include <QDebug>
#include <QSettings>
#include <QProcess>

#include <windows.h>
#include <wininet.h>

#pragma comment(lib,"Wininet.lib")
#pragma comment(lib,"Advapi32.lib")
#pragma comment(lib, "user32.lib")
#pragma comment(lib, "shell32.lib")
#pragma comment(lib, "Gdi32.lib")



const float DEFAULT_DPI = 96.0;

using namespace std;

float winDpiScaleEx()
{
#ifdef Q_OS_MAC
    return 1.0;
#else
    float rt = 0;
    if (rt == 0) {
        HDC screen = GetDC(NULL);
        FLOAT dpiX = static_cast<FLOAT>( GetDeviceCaps( screen, LOGPIXELSX ) );
        ReleaseDC( 0, screen );

        rt = dpiX / DEFAULT_DPI;
        if (rt > 1)
            return rt * 0.8; //這里縮小了縮放比率,因為1.5倍或2倍會變得特別大
        return rt;
    }
    return rt;
#endif
}

int main(int argc, char *argv[])
{    
    QSettings settings(QSettings::NativeFormat, QSettings::UserScope,
              "Shanghai", "Client_debug");

    QString ba = settings.value("QT_SCALE_FACTOR").toByteArray();
    qDebug() << ba;
    if (!ba.isEmpty()) {
        qputenv("QT_SCALE_FACTOR", ba.toUtf8());
    }

    QApplication a(argc, argv);


    qDebug() << qgetenv("QT_SCALE_FACTOR");

    QString newba = QString::number((double)winDpiScaleEx());
    if (ba.compare(newba) != 0) {
        settings.setValue("QT_SCALE_FACTOR", newba);
        QProcess::startDetached(QString::fromLocal8Bit(argv[0]), QStringList());
        return 0;
    }


    qDebug() << QString::number((double)winDpiScaleEx()).toUtf8();

    MyMainWindow w;
    w.show();



    return a.exec();
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM