QT程序在不同dpi下的字体自适应问题

QT程序在不同dpi下的字体自适应问题

问题描述

​近日在做关于Qt的一个上位机项目,开发时使用的屏幕分辨率为1080*1902,开发完成后,传到笔记本上给导师展示的时候发现有些字体出现显示不全的情况(如下图所示),经过一番折腾,找到一个初步解决方案,故分享出来供大家讨论。
字体显示不全

问题分析

​该问题主要由于屏幕的dpi不同所致。dpi反映的是每英寸长度内的像素个数,屏幕的dpi大,每英寸内的像素个数多。Qt中控件的大小单位为像素,所以在高dpi下,控件会变小,低dpi下控件会变大。但Qt中字体的单位默认为磅,这意味着无论在什么显示器上显示同一磅值的字体,其大小是不会发生变化的。所以这就造成了矛盾,本来在低dpi屏幕下开发的应用程序,在高dpi屏幕上使用时就可能因控件变小而造成字体显示不全的情况。

问题解决

​ 通过上述分析,我们会很自然地想到,将字体的单位换算成像素就可以解决该问题了。

​ 下面给出换算公式:

								pixel = dpi*point/72

​ 其中pixel为像素值,point为磅值,dpi为开发时所使用屏幕的dpi值,注意一定时开发使用的屏幕的dpi值而不是当前使用的屏幕的dpi值。

QT获取屏幕dpi的方法:

double dpi = QApplication::primaryScreen()->logicalDotsPerInch();

​ 下面是我针对Qt应用所编写的类,其主要功能是搜索当前界面中指定的几类控件,并将文字的单位由磅转化为像素。

头文件

#ifndef FONTSELFADAPTION_H
#define FONTSELFADAPTION_H
#include <QWidget>
/**
 * @brief 该类主要用于解决因dpi不同导致的字体显示不全问题,目前支持对label、groupbox、RadioButton、
 *		  tableWidget、QComboBox、QPushButton中字体的转化,如有其他控件需求,可在selfAdaption中自
 *		  行添加
 */
class FontSelfAdaption
{
public:
    FontSelfAdaption(QWidget *widget,double dpi);
    void setDpiOfDevelopmentPC(double dpi);
    double getDpiOfDevelopmentPC();
    double getDpiOfThisPC();
    void selfAdaption();
private:
    QWidget *widget;
    double dpiOfDevelopmentPC;
    double dpiOfThisPC;
    inline double pointToDpiPixel(int fontPointSize);

};

#endif // FONTSELFADAPTION_H

源文件

#include "fontselfadaption.h"
#include <QApplication>
#include <QScreen>
#include <QLabel>
#include <QGroupBox>
#include <QRadioButton>
#include <QComboBox>
#include <QDebug>
#include <QTableWidget>
#include <QHeaderView>
/*
	构造函数,输入当前widget指针,一般为this,以及开发时屏幕的dpi
*/
FontSelfAdaption::FontSelfAdaption(QWidget *widget,double dpi)
{
    this->widget = widget;
    this->dpiOfDevelopmentPC = dpi;
}
void FontSelfAdaption::setDpiOfDevelopmentPC(double dpi){
    this->dpiOfDevelopmentPC = dpi;
}
double FontSelfAdaption::getDpiOfDevelopmentPC(){
    return this->dpiOfDevelopmentPC;
}
double FontSelfAdaption::getDpiOfThisPC(){
    return QApplication::primaryScreen()->logicalDotsPerInch();
}
inline double FontSelfAdaption::pointToDpiPixel(int fontPointSize){
    return dpiOfDevelopmentPC*fontPointSize/72.0;
}
/**
 * @brief FontSelfAdaption::SelfAdaption 该函数用于将字体大小单位由磅转化为像素,如果控件之间有包含关系,请先转化父控件,再转化子控件;
 */
void FontSelfAdaption::selfAdaption(){

    QVector<QWidget*> widgetVector,labelVector,groupBoxVector,comboVector,buttonVector,radioVector,tableVector,lineEditVector;
    QList<QWidget*> objectList = widget->findChildren<QWidget*>();//获取所有子控件
    for (int i = 0;i<objectList.size(); i++) { 
        if (objectList.at(i)->inherits("QGroupBox")) {
            groupBoxVector.push_back(objectList.at(i));
        }else if(objectList.at(i)->inherits("QLabel")){
            labelVector.push_back(objectList.at(i));
        }else if(objectList.at(i)->inherits("QComboBox")){
            comboVector.push_back(objectList.at(i));
        }else if(objectList.at(i)->inherits("QPushButton")){
            buttonVector.push_back(objectList.at(i));
        }else if(objectList.at(i)->inherits("QRadioButton")){
            radioVector.push_back(objectList.at(i));
        }else if(objectList.at(i)->inherits("QTableWidget")){
           //qDebug() << "table";
            tableVector.push_back(objectList.at(i));
        }else if(objectList.at(i)->inherits("QLineEdit")){
            lineEditVector.push_back(objectList.at(i));
        }
    }
    //对子控件进行排序,包含其他控件的控件放在前面,防止Qss被覆盖
    widgetVector.append(groupBoxVector);
    widgetVector.append(labelVector);
    widgetVector.append(comboVector);
    widgetVector.append(buttonVector);
    widgetVector.append(radioVector);
    widgetVector.append(lineEditVector);
    QVector<double>widgetPixelVector;
    for (int i=0;i<widgetVector.size();i++) {
        widgetPixelVector.push_back(pointToDpiPixel(widgetVector.at(i)->fontInfo().pointSize()));
    }
    for (int i = 0; i<widgetVector.size();i++) {
        widgetVector.at(i)->setStyleSheet("font-size:"+QString::number(static_cast<int>(widgetPixelVector.at(i)+0.5))+"px");
    }
    //牵扯到表头,对表格单独处理
    for (int i =0;i<tableVector.size();i++) {
        QTableWidget* tableWidget =  static_cast<QTableWidget*>(tableVector.at(i));
        tableWidget->horizontalHeader()->setStyleSheet("font-size:"+QString::number(static_cast<int>(pointToDpiPixel(9)+0.5))+"px");
        tableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
        tableWidget->setStyleSheet("font-size:"+QString::number(static_cast<int>(pointToDpiPixel(9)+0.5))+"px");
    }

}

程序使用说明

	FontSelfAdaption f(this,dpi); //this为当前widget的指针,dpi为开发时所有屏幕的dpi
	f.selfAdaption();
结果与问题

通过处理后的界面如下图所示
在这里插入图片描述
由此可以看到文字已经可以完全显示了,但是也存在着字体变小的问题,如果各位对该问题有更好的解决方法,可以一起讨论。

  • 10
    点赞
  • 52
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值