Qt 下的DPI问题解决

CBaseDlg
#ifndef BASEDLG_H
#define BASEDLG_H

#include <QDialog>

class CBaseDlg : public QDialog
{
    Q_OBJECT

    enum ResizeRegion
    {
        Default,
        North,
        NorthEast,
        East,
        SouthEast,
        South,
        SouthWest,
        West,
        NorthWest
    };

public:
    explicit CBaseDlg(QWidget *parent = nullptr);
    ~CBaseDlg() override;

    void setDragToolbarHeight(int height) {m_iDragToolbarHeight = height;}
    bool IsMoving() { return m_bDrag && m_bMove; }

signals:
    void sigDragPosChanged(QWidget * sender, int relativeX, int relativeY);

protected:
    void keyPressEvent(QKeyEvent *event) override;

    void mousePressEvent(QMouseEvent *event) override;
    void mouseMoveEvent(QMouseEvent *event) override;
    void mouseReleaseEvent(QMouseEvent *event) override;

    void showEvent(QShowEvent *event) override;
    bool nativeEvent(const QByteArray &eventType, void *message, long *result) override;

    virtual void onDpiChanged();

	virtual void setAllbtnDefautlFalse();
    void setCenterWindowOnShowFirstly(bool bCenterWindowOnShowFirstly) { m_bCenterWindowOnShowFirstly = bCenterWindowOnShowFirstly; }
    void centerWindow();

    bool                m_bFirstShow;
    double              m_fStretchFactor; // dpi stretch factor

    static const unsigned int DPI_BASE_VALUE = 96;

private:
    int                 m_iDragToolbarHeight;

    bool                m_bDrag;
    bool                m_bMove;
    QPoint              dragPos;
    QPoint              m_resizeDownPos;
    const int           m_resizeBorderWidth = 8;
    ResizeRegion        m_resizeRegion;
    QRect               m_mouseDownRect;
    bool                m_bCanResize;
    bool                m_bCenterWindowOnShowFirstly;
    unsigned int        m_uDpi;

    void setResizeCursor(ResizeRegion region);
    ResizeRegion getResizeRegion(QPoint clientPos);
    void handleMove(QPoint pt);
    void handleResize();
    void updateDpi(unsigned int uDpi);
    void changePosOnDrag(const QPoint & newPos);
};

#endif // BASEDLG_H
#include "base-dlg.h"

#if defined(WIN32)

#include <Windows.h>

#endif

#include <QMouseEvent>
#include <QIcon>
#include <QDesktopWidget>
#include <QDebug>
#include <QApplication>
#include <QScreen>
#include <QPushButton>
#include <QBitmap>
#include <QPainter>
#include <QDebug>

CBaseDlg::CBaseDlg(QWidget *parent) :
    QDialog(parent)
//    , m_bDrag(false)
    , m_bFirstShow(true)
    , m_fStretchFactor(0)
    , m_iDragToolbarHeight(0)
    , m_bDrag(false)
    , m_bMove(false)
    , m_bCanResize(false)
    , m_bCenterWindowOnShowFirstly(true)
    , m_uDpi(0)
{
    setWindowIcon(QIcon(":/resources/images/logo_about.png"));

    setWindowFlags(Qt::FramelessWindowHint);
    setMouseTracking(true);
}

CBaseDlg::~CBaseDlg()
{

}

void CBaseDlg::keyPressEvent(QKeyEvent *event)
{
    switch (event->key())
    {
    case Qt::Key_Escape:
        break;
    default:
        QDialog::keyPressEvent(event);
    }
}

void CBaseDlg::mousePressEvent(QMouseEvent *event)
{

    if (event->button() == Qt::LeftButton && Qt::WindowMaximized != windowState()) {
        this->m_bDrag = true;
        this->dragPos = event->pos();
        this->m_resizeDownPos = event->globalPos();
        this->m_mouseDownRect = this->rect();
    }

    QDialog::mousePressEvent(event);
}

void CBaseDlg::mouseMoveEvent(QMouseEvent *event)
{
    if (m_resizeRegion != Default)
    {
        handleResize();
        return;
    }
    if(m_bMove) {
        changePosOnDrag(event->globalPos() - dragPos);
        return;
    }
    QPoint clientCursorPos = event->pos();
    QRect r = this->rect();
    QRect resizeInnerRect(0, 0, r.width() - m_resizeBorderWidth, r.height() - m_resizeBorderWidth);
    if(r.contains(clientCursorPos) && !resizeInnerRect.contains(clientCursorPos)) { // adjust dialog size
        if (!m_bCanResize)
        {
            return;
        }
        ResizeRegion resizeReg = getResizeRegion(clientCursorPos);
        setResizeCursor(resizeReg);
        if (m_bDrag && (event->buttons() & Qt::LeftButton)) {
            m_resizeRegion = resizeReg;
            handleResize();
        }
    }
    else { // move dialog
        setCursor(Qt::ArrowCursor);
        if (event->y() > m_iDragToolbarHeight)
        {
            // the dialog can only be dragged on the tool bar
            return;
        }
        if (m_bDrag && (event->buttons() & Qt::LeftButton)) {
            m_bMove = true;
            changePosOnDrag(event->globalPos() - dragPos);
        }
    }

    QDialog::mouseMoveEvent(event);
}

void CBaseDlg::mouseReleaseEvent(QMouseEvent *event)
{
//    if(event->button() == Qt::LeftButton)
//    {
//        m_bDrag = false;
//    }


    m_bDrag = false;
    if(m_bMove) {
        m_bMove = false;
        handleMove(event->globalPos()); // bind to top/left/right of screen if out of screen on mouse release
    }
    m_resizeRegion = Default;
    setCursor(Qt::ArrowCursor);

    QDialog::mouseReleaseEvent(event);
}

void CBaseDlg::showEvent(QShowEvent *event)
{
    if (m_bFirstShow) {
        m_bFirstShow = false;
        if (m_bCenterWindowOnShowFirstly)
        {
            centerWindow();
        }
    }

    QScreen * pScreen = QGuiApplication::screenAt(QPoint(this->x() + this->width() / 2, this->y() + this->height() / 2));
    if (pScreen)
        updateDpi(static_cast<unsigned int>(pScreen->logicalDotsPerInchX()));

    QDialog::showEvent(event);
}

void CBaseDlg::centerWindow()
{
    qDebug() << this;
    QPoint point(this->x() + this->width() / 2, this->y() + this->height() / 2);
    QScreen * pScreen = QGuiApplication::screenAt(point);
    if (nullptr == pScreen)
    {
        qDebug() << "Failed to centerWindow for invalid screen, point:" << point;
        pScreen = QGuiApplication::primaryScreen();
        if (nullptr == pScreen)
        {
            qDebug() << "Failed to position screen by primaryScreen";
            return;
        }
    }
    qDebug() << "screen name:" << pScreen->name() << ", logicalDotsPerInchX: " << pScreen->logicalDotsPerInchX() << "logicalDotsPerInchY: " << pScreen->logicalDotsPerInchY();

    QRect rect = pScreen->availableGeometry();
    qDebug() << "Current screen availableGeometry:" << rect << ", geometry:" << pScreen->geometry();

    int ax = rect.left() + (rect.width() - this->width()) / 2;
    int ay = rect.top() + (rect.height() - this->height()) / 2;

    qDebug() << "Move window to " << ax << ay;
    move(ax, ay);
}

bool CBaseDlg::nativeEvent(const QByteArray &eventType, void *message, long *result)
{
#if defined(WIN32)
    MSG* pMsg = reinterpret_cast<MSG*>(message);

    switch (pMsg->message)
    {
    case WM_DPICHANGED:
    {
        WORD dpi = LOWORD(pMsg->wParam);
        qDebug() << "WM_DPICHANGED:" << dpi;
        updateDpi(dpi);
//        QRect rect = QApplication::desktop()->availableGeometry();
//        QGuiApplication::screens();
//        qInfo() << "availableGeometry:" << rect.width() << rect.height();
    }
    }
#endif
    return QDialog::nativeEvent(eventType, message, result);
}

//void CBaseDlg::onDpiChanged(unsigned int dpi)
//{
//    qDebug() << "dpi:" << dpi << ", objectName" << this->objectName();
    double dpiRatio = dpi / 96.0;
    QString qstrFileName;
    if (dpiRatio > 1)
    {
        qstrFileName = ":/resources/qss/dialog-1.5x.qss";
    }
    else{
        qstrFileName = ":/resources/qss/dialog.qss";
    }
    this->setFixedWidth(800 * dpiRatio);
    this->setFixedHeight(600 * dpiRatio);
    QString qss;
    QFile qssFile(qstrFileName);
    qssFile.open(QFile::ReadOnly);
    if(qssFile.isOpen()) {
        qss = QLatin1String(qssFile.readAll());
        this->setStyleSheet(qss);
        qssFile.close();

        qDebug() << __FUNCTION__ << __LINE__ << qssFile.fileName();
    }
    else
    {
        qDebug() << __FUNCTION__ << __LINE__ << qssFile.errorString();
    }

    ui->m_pLblText->adjustSize();
//}

void CBaseDlg::setAllbtnDefautlFalse()
{
	QList<QPushButton*> list = findChildren<QPushButton*>();
	for (int i = 0; i < list.size(); ++i)
	{
		QPushButton *pb = list.at(i);
		pb->setAutoDefault(false);
		pb->setDefault(false);
	}
}

void CBaseDlg::setResizeCursor(ResizeRegion region)
{
    switch (region)
    {
    case North:
    case South:
        setCursor(Qt::SizeVerCursor);
        break;
    case East:
    case West:
        setCursor(Qt::SizeHorCursor);
        break;
    case NorthWest:
    case SouthEast:
        setCursor(Qt::SizeFDiagCursor);
        break;
    default:
        setCursor(Qt::SizeBDiagCursor);
        break;
    }
}
CBaseDlg::ResizeRegion CBaseDlg::getResizeRegion(QPoint clientPos)
{
    if (clientPos.y() <= m_resizeBorderWidth) {
        if (clientPos.x() <= m_resizeBorderWidth)
            return NorthWest;
        else if (clientPos.x() >= this->width() - m_resizeBorderWidth)
            return NorthEast;
        else
            return North;
    }
    else if (clientPos.y() >= this->height() - m_resizeBorderWidth) {
        if (clientPos.x() <= m_resizeBorderWidth)
            return SouthWest;
        else if (clientPos.x() >= this->width() - m_resizeBorderWidth)
            return SouthEast;
        else
            return South;
    }
    else {
        if (clientPos.x() <= m_resizeBorderWidth)
            return West;
        else
            return East;
    }
}
void CBaseDlg::handleMove(QPoint pt)
{
    QPoint currentPos = pt - dragPos;
//    if(currentPos.x()<desktop->x()) { // bind to left
//        currentPos.setX(desktop->x());
//    }
//    else if (currentPos.x()+this->width()>desktop->width()) { // bind to right
//        currentPos.setX(desktop->width()-this->width());
//    }
//    if(currentPos.y()<desktop->y()) { // bind to top
//        currentPos.setY(desktop->y());
//    }
    changePosOnDrag(currentPos);
}
void CBaseDlg::handleResize()
{
    int xdiff = QCursor::pos().x() - m_resizeDownPos.x();
    int ydiff = QCursor::pos().y() - m_resizeDownPos.y();
    switch (m_resizeRegion)
    {
    case East:
    {
        resize(m_mouseDownRect.width()+xdiff, this->height());
        break;
    }
    case West:
    {
        resize(m_mouseDownRect.width()-xdiff, this->height());
        move(m_resizeDownPos.x()+xdiff, this->y());
        break;
    }
    case South:
    {
        resize(this->width(),m_mouseDownRect.height()+ydiff);
        break;
    }
    case North:
    {
        resize(this->width(),m_mouseDownRect.height()-ydiff);
        move(this->x(), m_resizeDownPos.y()+ydiff);
        break;
    }
    case SouthEast:
    {
        resize(m_mouseDownRect.width() + xdiff, m_mouseDownRect.height() + ydiff);
        break;
    }
    case NorthEast:
    {
        resize(m_mouseDownRect.width()+xdiff, m_mouseDownRect.height()-ydiff);
        move(this->x(), m_resizeDownPos.y()+ydiff);
        break;
    }
    case NorthWest:
    {
        resize(m_mouseDownRect.width()-xdiff, m_mouseDownRect.height()-ydiff);
        move(m_resizeDownPos.x()+xdiff, m_resizeDownPos.y()+ydiff);
        break;
    }
    case SouthWest:
    {
        resize(m_mouseDownRect.width()-xdiff, m_mouseDownRect.height()+ydiff);
        move(m_resizeDownPos.x()+xdiff, this->y());
        break;
    }
    }
}

void CBaseDlg::updateDpi(unsigned int uDpi)
{
    qDebug() << uDpi << this;
    if (m_uDpi == uDpi)
    {
        qDebug() << "Dpi not changed";
        return;
    }

    m_uDpi = uDpi;
    double ratio = static_cast<double>(uDpi) / static_cast<double>(DPI_BASE_VALUE);
    double fStretchFactor = 1;
    if (ratio >= 2)
    {
        fStretchFactor = 2;
    }
    else if (ratio >= 1.5)
    {
        fStretchFactor = 1.5;
    }
    else
    {
        fStretchFactor = 1;
    }
    qDebug() << "fStretchFactor:" << fStretchFactor;

    m_fStretchFactor = fStretchFactor;
    onDpiChanged();
}

void CBaseDlg::onDpiChanged()
{
    qDebug();
}

void CBaseDlg::changePosOnDrag(const QPoint & newPos)
{
    QPoint curPos(this->pos());
    move(newPos);
//    qDebug() << "curPos:" << curPos << ", newPos:" << newPos << ", this:" << this;
    emit sigDragPosChanged(this, newPos.x() - curPos.x(), newPos.y() - curPos.y());
}
CDpiAdjustTool
#ifndef CDPIADJUSTTOOL_H
#define CDPIADJUSTTOOL_H

#include <QMap>
#include <QLayout>
#include <QLayoutItem>

class dataLayoutItem
{
public:
    int s_type;//0 widget, 1 layout, 2 spacerItem

    //0
    int s_baseWidth;
    int s_baseHeight;
    QSizePolicy s_sizePolicy;
    QSize s_minSize;
    QSize s_maxSize;

    //1
    int s_marginLeft;
    int s_marginTop;
    int s_marginRight;
    int s_marginBottom;
    int s_spacing;

    //2
    int s_sp_width;
    int s_sp_height;
    QSizePolicy s_sp_sizePolicy;
};

class CDpiAdjustTool
{
public:
    CDpiAdjustTool() 
        : m_fStretchFactor(0)
        , m_baseWidth(0)
        , m_baseHeight(0)
    {

    }

    int m_baseWidth;
    int m_baseHeight;
    QMap< QLayoutItem*, dataLayoutItem> controldata;
    //
    double m_fStretchFactor;

    void adjustSizeWidget(QWidget* curWidget = nullptr);
    void adjustSizeLayout(QLayout* curLayout = nullptr);
    //
    void updateSizeWidget(QWidget* curWidget = nullptr);
    void updateSizeLayout(QLayout* curLayout = nullptr);
    //
    void setAutoSizeWidget(QWidget* pWidget, QLayoutItem* pLayoutItem);
    void setAutoSizeLayout(QLayout* pLayout, QLayoutItem* pLayoutItem);
    void setAutoSizeSpacerItem(QSpacerItem* pSpacerItem, QLayoutItem* pLayoutItem);
    //
    void addDataWidget(QWidget* pWidget, QLayoutItem* pLayoutItem);
    void addDataLayout(QLayout* pLayout, QLayoutItem* pLayoutItem);
    void addDataSpacerItem(QSpacerItem* pSpacerItem, QLayoutItem* pLayoutItem);

    void clearData();
    void init(int baseWidth, int baseHeight, QWidget* pWidget);
    void update(double stretchFactor, QWidget* pWidget);
    void updateChilds(double stretchFactor, QWidget* pWidget, bool resizeflag);
};

#endif // CDPIADJUSTTOOL_H
#include "dpi-adjust-tool.h"
#include <QTabWidget>
#include <QScrollArea>
#include <QStackedWidget>
#include <QDialogButtonBox>
#include <QMessageBox>
#include <QDebug>

void CDpiAdjustTool::clearData()
{
    controldata.clear();
}

void CDpiAdjustTool::init(int baseWidth, int baseHeight, QWidget* pWidget)
{
    if (m_baseWidth == 0 && m_baseHeight == 0)
    {
        m_baseWidth = baseWidth;
        m_baseHeight = baseHeight;
        updateSizeWidget(pWidget);
    }
}

void CDpiAdjustTool::update(double stretchFactor, QWidget* pWidget)
{
    if (pWidget && m_baseWidth != 0 && m_baseHeight != 0)
    {
        m_fStretchFactor = stretchFactor;
        adjustSizeWidget(pWidget);
        pWidget->setFixedSize(m_baseWidth * m_fStretchFactor, m_baseHeight * m_fStretchFactor);
    }
}

void CDpiAdjustTool::updateChilds(double stretchFactor, QWidget* pWidget, bool resizeflag)
{
    if (pWidget && m_baseWidth != 0&& m_baseHeight != 0)
    {
        m_fStretchFactor = stretchFactor;
        adjustSizeWidget(pWidget);
        if (resizeflag)
        {
            pWidget->setFixedSize(m_baseWidth * m_fStretchFactor, m_baseHeight * m_fStretchFactor);
        }
    }
}

void CDpiAdjustTool::updateSizeWidget(QWidget* curWidget)
{
    if (curWidget)
    {
        QLayout* layout = curWidget->layout();
        addDataLayout(layout, (QLayoutItem*)layout);
        updateSizeLayout(layout);
    }
}

void CDpiAdjustTool::updateSizeLayout(QLayout* curLayout)
{
    if (curLayout)
    {
        int iCount = curLayout->count();
        for (int i = 0; i < iCount; i++)
        {
            QLayoutItem* pLayoutItem = curLayout->itemAt(i);

            QWidget* x1 = pLayoutItem->widget();
            QLayout* x2 = pLayoutItem->layout();
            QSpacerItem* x3 = pLayoutItem->spacerItem();
            if (x1 != nullptr)
            {
                addDataWidget(x1, pLayoutItem);

                updateSizeWidget(x1);

                const QMetaObject *metaObj = x1->metaObject();
                QString className = metaObj->className();
                if (className == "QTabWidget")
                {
                    QTabWidget* pTabWidget = (QTabWidget*)x1;
                    int iTab = pTabWidget->count();
                    for (int j = 0; j < iTab; j++)
                    {
                        QWidget* pTab = pTabWidget->widget(j);
                        if (pTab)
                        {
                            addDataWidget(pTab, (QLayoutItem*)pTab);
                            updateSizeWidget(pTab);
                        }
                    }

                }
                else if (className == "QScrollArea")
                {
                    QScrollArea* pScrollArea = (QScrollArea*)x1;
                    QWidget* pScroll = pScrollArea->widget();
                    if (pScroll)
                    {
                        controldata.remove(pLayoutItem);
                        addDataWidget(pScroll, (QLayoutItem*)pScroll);
                        updateSizeWidget(pScroll);
                    }
                }
                else if (className == "QStackedWidget")
                {
                    QStackedWidget* pStackedWidget = (QStackedWidget*)x1;
                    int iTab = pStackedWidget->count();
                    for (int k = 0; k < iTab; k++)
                    {
                        QWidget* pTab = pStackedWidget->widget(i);
                        if (pTab)
                        {
                            addDataWidget(pTab, (QLayoutItem*)pTab);
                            updateSizeWidget(pTab);
                        }
                    }
                }
                else if (className == "QDialogButtonBox")
                {
                    QDialogButtonBox* pDialogButtonBox = (QDialogButtonBox*)x1;
                    QPushButton* ibutton = pDialogButtonBox->button(QDialogButtonBox::Ok);
                    if (ibutton)
                    {
                        addDataWidget((QWidget*)ibutton, (QLayoutItem*)ibutton);
                        ibutton = nullptr;
                    }
                    ibutton = pDialogButtonBox->button(QDialogButtonBox::Yes);
                    if (ibutton)
                    {
                        addDataWidget((QWidget*)ibutton, (QLayoutItem*)ibutton);
                        ibutton = nullptr;
                    }
                    ibutton = pDialogButtonBox->button(QDialogButtonBox::Cancel);
                    if (ibutton)
                    {
                        addDataWidget((QWidget*)ibutton, (QLayoutItem*)ibutton);
                        ibutton = nullptr;
                    }
                    ibutton = pDialogButtonBox->button(QDialogButtonBox::No);
                    if (ibutton)
                    {
                        addDataWidget((QWidget*)ibutton, (QLayoutItem*)ibutton);
                        ibutton = nullptr;
                    }
                }
            }
            if (x2 != nullptr)
            {
                addDataLayout(x2, pLayoutItem);

                updateSizeLayout(x2);
            }
            if (x3 != nullptr)
            {
                addDataSpacerItem(x3, pLayoutItem);
            }
        }
    }
}

void CDpiAdjustTool::adjustSizeWidget(QWidget* curWidget)
{
    if (curWidget)
    {
        QLayout* layout = curWidget->layout();
        setAutoSizeLayout(layout, (QLayoutItem*)layout);
        adjustSizeLayout(layout);
    }
}

void CDpiAdjustTool::adjustSizeLayout(QLayout* curLayout)
{
    if (curLayout)
    {
        int iCount = curLayout->count();
        for (int i = 0; i < iCount; i++)
        {
            QLayoutItem* pLayoutItem = curLayout->itemAt(i);

            QWidget* x1 = pLayoutItem->widget();
            QLayout* x2 = pLayoutItem->layout();
            QSpacerItem* x3 = pLayoutItem->spacerItem();
            if (x1 != nullptr)
            {
                if (controldata.contains(pLayoutItem))
                {
                    setAutoSizeWidget(x1, pLayoutItem);
                }
                else
                {
                    addDataWidget(x1, pLayoutItem);
                }
                adjustSizeWidget(x1);

                const QMetaObject *metaObj = x1->metaObject();
                QString className = metaObj->className();
                if (className == "QTabWidget")
                {
                    QTabWidget* pTabWidget = (QTabWidget*)x1;
                    int iTab = pTabWidget->count();
                    for (int j = 0; j < iTab; j++)
                    {
                        QWidget* pTab = pTabWidget->widget(j);
                        if (pTab)
                        {
                            setAutoSizeWidget(pTab, (QLayoutItem*)pTab);
                            adjustSizeWidget(pTab);
                        }
                    }

                }
                else if (className == "QScrollArea")
                {
                    QScrollArea* pScrollArea = (QScrollArea*)x1;
                    QWidget* pScroll = pScrollArea->widget();
                    if (pScroll)
                    {
                        controldata.remove(pLayoutItem);
                        setAutoSizeWidget(pScroll, (QLayoutItem*)pScroll);
                        adjustSizeWidget(pScroll);
                    }
                }
                else if (className == "QStackedWidget")
                {
                    QStackedWidget* pStackedWidget = (QStackedWidget*)x1;
                    int iTab = pStackedWidget->count();
                    for (int k = 0; k < iTab; k++)
                    {
                        QWidget* pTab = pStackedWidget->widget(i);
                        if (pTab)
                        {
                            setAutoSizeWidget(pTab, (QLayoutItem*)pTab);
                            adjustSizeWidget(pTab);
                        }
                    }
                }
                else if (className == "QDialogButtonBox")
                {
                    QDialogButtonBox* pDialogButtonBox = (QDialogButtonBox*)x1;
                    QPushButton* ibutton = pDialogButtonBox->button(QDialogButtonBox::Ok);
                    if (ibutton)
                    {
                        setAutoSizeWidget((QWidget*)ibutton, (QLayoutItem*)ibutton);
                        ibutton = nullptr;
                    }
                    ibutton = pDialogButtonBox->button(QDialogButtonBox::Yes);
                    if (ibutton)
                    {
                        setAutoSizeWidget((QWidget*)ibutton, (QLayoutItem*)ibutton);
                        ibutton = nullptr;
                    }
                    ibutton = pDialogButtonBox->button(QDialogButtonBox::Cancel);
                    if (ibutton)
                    {
                        setAutoSizeWidget((QWidget*)ibutton, (QLayoutItem*)ibutton);
                        ibutton = nullptr;
                    }
                    ibutton = pDialogButtonBox->button(QDialogButtonBox::No);
                    if (ibutton)
                    {
                        setAutoSizeWidget((QWidget*)ibutton, (QLayoutItem*)ibutton);
                        ibutton = nullptr;
                    }
                }
            }
            if (x2 != nullptr)
            {
                if (controldata.contains(pLayoutItem))
                {
                    setAutoSizeLayout(x2, pLayoutItem);
                }
                else
                {
                    addDataLayout(x2, pLayoutItem);
                }
                adjustSizeLayout(x2);
            }
            if (x3 != nullptr)
            {
                if (controldata.contains(pLayoutItem))
                {
                    setAutoSizeSpacerItem(x3, pLayoutItem);
                }
                else
                {
                    addDataSpacerItem(x3, pLayoutItem);
                }
            }
        }
    }
}

void CDpiAdjustTool::setAutoSizeWidget(QWidget* pWidget, QLayoutItem* pLayoutItem)
{
    if (pWidget && pLayoutItem)
    {
        dataLayoutItem data = controldata[pLayoutItem];
        if (data.s_type == 0)
        {
            pWidget->resize(data.s_baseWidth * m_fStretchFactor, data.s_baseHeight * m_fStretchFactor);
            bool bsetSize = data.s_sizePolicy.horizontalPolicy() == QSizePolicy::Fixed || data.s_minSize.width() == data.s_maxSize.width();
            if (bsetSize)
            {
                pWidget->setFixedWidth(data.s_baseWidth * m_fStretchFactor);
            }
            else
            {
                pWidget->setMinimumWidth(data.s_minSize.width() * m_fStretchFactor);
                if (data.s_maxSize.width() < 8000)
                {
                    pWidget->setMaximumWidth(data.s_maxSize.width() * m_fStretchFactor);
                }
            }

            bsetSize = data.s_sizePolicy.verticalPolicy() == QSizePolicy::Fixed || data.s_minSize.height() == data.s_maxSize.height();
            if (bsetSize)
            {
                pWidget->setFixedHeight(data.s_baseHeight * m_fStretchFactor);
            }
            else
            {
                pWidget->setMinimumHeight(data.s_minSize.height() * m_fStretchFactor);
                if (data.s_maxSize.height() < 8000)
                {
                    pWidget->setMaximumHeight(data.s_maxSize.height() * m_fStretchFactor);
                }
            }
        }

        /*qInfo() << "ObjectName:" << pWidget->objectName() << "====================================";
        qInfo() << "size:" << pWidget->size();
        qInfo() << "Policy:" << pWidget->sizePolicy();
        qInfo() << "minSize" << pWidget->minimumSize();
        qInfo() << "maxSize" << pWidget->maximumSize();
        qInfo() << "end========================================";*/
    }
}

void CDpiAdjustTool::setAutoSizeLayout(QLayout* pLayout, QLayoutItem* pLayoutItem)
{
    if (pLayout && pLayoutItem)
    {
        dataLayoutItem data = controldata[pLayoutItem];
        if (data.s_type == 1)
        {
            pLayout->setSpacing(data.s_spacing * m_fStretchFactor);
            pLayout->setContentsMargins(data.s_marginLeft * m_fStretchFactor, data.s_marginTop * m_fStretchFactor, data.s_marginRight * m_fStretchFactor, data.s_marginBottom * m_fStretchFactor);
        }
    }
}

void CDpiAdjustTool::setAutoSizeSpacerItem(QSpacerItem* pSpacerItem, QLayoutItem* pLayoutItem)
{
    if (pSpacerItem && pLayoutItem)
    {
        dataLayoutItem data = controldata[pLayoutItem];
        if (data.s_type == 2)
        {
            bool nflag = pSpacerItem->sizePolicy().expandingDirections() == data.s_sizePolicy.expandingDirections() && 
                    (data.s_sp_sizePolicy.horizontalPolicy() == QSizePolicy::Fixed ||
                    data.s_sp_sizePolicy.verticalPolicy() == QSizePolicy::Fixed);
            if (nflag)
            {
                pLayoutItem->invalidate();
                pSpacerItem->changeSize(data.s_sp_width * m_fStretchFactor, data.s_sp_height * m_fStretchFactor, data.s_sp_sizePolicy.horizontalPolicy(), data.s_sp_sizePolicy.verticalPolicy());
            }
        }
    }
}

void CDpiAdjustTool::addDataWidget(QWidget* pWidget, QLayoutItem* pLayoutItem)
{
    if (pWidget && pLayoutItem)
    {
        dataLayoutItem data;
        data.s_type = 0;
        data.s_baseWidth = pWidget->width();
        data.s_baseHeight = pWidget->height();
        data.s_sizePolicy = pWidget->sizePolicy();
        data.s_minSize = pWidget->minimumSize();
        data.s_maxSize = pWidget->maximumSize();
        controldata[pLayoutItem] = data;

        /*qInfo() << "ObjectName:" << pWidget->objectName() << "====================================";
        qInfo() << "basesize:" << data.s_baseWidth << data.s_baseHeight;
        qInfo() << "Policy:" << data.s_sizePolicy;
        qInfo() << "minSize" << data.s_minSize;
        qInfo() << "maxSize" << data.s_maxSize;
        qInfo() << "end========================================";*/
    }
}

void CDpiAdjustTool::addDataLayout(QLayout* pLayout, QLayoutItem* pLayoutItem)
{
    if (pLayout && pLayoutItem)
    {
        dataLayoutItem data;
        data.s_type = 1;
        pLayout->getContentsMargins(&data.s_marginLeft, &data.s_marginTop, &data.s_marginRight, &data.s_marginBottom);
        data.s_spacing = pLayout->spacing();
        controldata[pLayoutItem] = data;
    }
}

void CDpiAdjustTool::addDataSpacerItem(QSpacerItem* pSpacerItem, QLayoutItem* pLayoutItem)
{
    if (pSpacerItem && pLayoutItem)
    {
        QSize nsize = pSpacerItem->sizeHint();
        
        dataLayoutItem data;
        data.s_type = 2;
        data.s_sp_width = nsize.width();
        data.s_sp_height = nsize.height();
        data.s_sp_sizePolicy = pSpacerItem->sizePolicy();
        controldata[pLayoutItem] = data;
    }
}

Demo地址

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
如果你的Qt应用程序在高缩放级别(如225%)下显示不完全,可能是因为你的应用程序没有正确处理高DPI缩放。你可以使用以下方法来解决这个问题: 1. 设置Qt应用程序的高DPI缩放因子:在应用程序的main()函数中,使用QApplication::setAttribute()方法来启用高DPI支持,并使用QApplication::setHighDpiScaleFactor()方法来设置高DPI缩放因子。例如,下面的代码将应用程序的高DPI缩放因子设置为2.25: ``` int main(int argc, char *argv[]) { QApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QApplication app(argc, argv); app.setHighDpiScaleFactor(2.25); ... } ``` 2. 使用Qt的布局管理器:使用Qt的布局管理器可以确保你的应用程序在不同的窗口大小和分辨率下正确地缩放和显示。如果你的应用程序没有使用布局管理器,请尝试将其添加到你的界面中。 3. 使用像素密度独立的字体:Qt的字体类支持像素密度独立的字体,这些字体可以在不同的分辨率和缩放下正确显示。你可以使用QFont类的setPixelSize()方法来设置像素密度独立的字体大小。 4. 使用矢量图形:矢量图形可以无损地缩放,因此它们是在高分辨率屏幕上正确显示的理想选择。Qt支持许多矢量图形格式,如SVG和PDF。 如果你的应用程序已经使用了上述方法,但仍然在高缩放级别下显示不完全,请确保你的应用程序没有使用绝对像素值来定位和调整界面元素的大小和位置。相反,你应该使用相对像素值(例如百分比)或像素密度独立的值来调整界面元素的大小和位置。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

黄权浩

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值