Implementing High DPI Scaling in Qt Applications

Core Frmaework Components

The high DPI scaling solution revolves around three key components:

  1. DPI Change Detection Interface (ICallDPIChanged)
  2. DPI Management System (IDPIHelper)
  3. Floating Widget Controller

DPI Change Detection Interface

struct DPIChangeHandler {
    virtual void handleScaleChange(float newScale) = 0;
    virtual WindowID getWindowID() const = 0;
    virtual void updateScale(float scale) = 0;
};

DPI Management System

const float BASE_DPI = 96.0f;

struct DPIManager {
    virtual bool handleDPIChange(unsigned short dpi, WindowID window) = 0;
    virtual void removeWindowRecord(WindowID window) = 0;
    virtual float getCurrentScale(WindowID window) const = 0;
    virtual float getPreviousScale(WindowID window) const = 0;
    virtual QString getStyleContent(WindowID window) const = 0;
    virtual float getScaledValue(float value, WindowID window) const = 0;
};

Implementation Strategy

Window Size Adaptation

class ScaledWidget : public QWidget, public DPIChangeHandler {
    Q_OBJECT
public:
    void resize(int width, int height) override {
        sizeFlags |= SizeAction::Resize;
        baseSize = QSize(width, height);
        QWidget::resize(baseSize * currentScale);
    }
    
    // Other size-related overrides...
};

Font Scaling

QString scaleStyleSheet(const QString& original, float scale) {
    if (qFuzzyCompare(scale, 1.0f)) return original;
    
    QString scaled = original;
    QRegularExpression sizePattern("\\d+px");
    auto match = sizePattern.match(scaled);
    
    while (match.hasMatch()) {
        int pxValue = match.captured().replace("px", "").toInt();
        int scaledValue = qRound(pxValue * scale);
        scaled.replace(match.capturedStart(), match.capturedLength(), 
                      QString::number(scaledValue) + "px");
        match = sizePattern.match(scaled, match.capturedEnd());
    }
    return scaled;
}

Icon Handling

float calculateImageScaleFactor(float dpiScale) {
    if (dpiScale < 1.5f) return dpiScale;
    if (dpiScale < 2.5f) return dpiScale / 2;
    if (dpiScale < 3.5f) return dpiScale / 3;
    return dpiScale / 3; // Default to 3x scaling
}

Floating Widget Management

class FloatingWidgetController : public QObject {
    Q_OBJECT
public:
    static FloatingWidgetController* instance();
    
    void registerWidget(QWidget* widget);
    void notifyDPIChange(WindowID window, float newScale);
    
private:
    QSet<DPIChangeHandler*> managedWidgets;
};

Tags: Qt High DPI UI Scaling cross-platform C++

Posted on Tue, 29 Sep 2026 16:13:56 +0000 by fleabel