IT 알쓸신잡

Qt 에서 High DPI 적용 본문

Development

Qt 에서 High DPI 적용

솦트웰러 2023. 3. 7. 19:47
728x90
반응형

오늘의 주제는 High DPI 입니다.

High DPI 는 뭐고 어떤 기능을 하는건가요?

 

DPI는 Density Per Inch 의 약자로 인치 당 밀도를 뜻합니다.

말그대로 High DPI는 인치당 밀도가 높다 정도가 되겠네요.

 

보통 노트북과 같이 작은 모니터에 큰 해상도를 출력하기 위해서는 아이콘이나 텍스트가 작아지게 됩니다. 그러면 보기가 너무 불편할겁니다. 또 요즘은 4K 모니터가 많이 나오고 있는데 모니터 사이즈는 기존과 같이 27인치인데 Full HD 에서 4K를 출력하기 위해서는 4배 정도의 아이콘과 텍스트가 작아지게 되서 불편하게 됩니다.

 

이때 DPI를 높여주게 되면 인치 당 픽셀 밀도가 높아져서 아이콘과 텍스트가 커지게 되고 사용자가 윈도우를 편하게 사용할 수 있게 되는거죠~

 

그럼 High DPI는 어디서 설정을 할까요?

윈도우의 디스플레이 설정에  보면 배율이라고 있습니다. 이게 보통은 100% 일 꺼에요.

이걸 125%, 150%, 200% 설정을 변경하게 되면 아이콘과 텍스트 사이즈가 커지게 됩니다.

 

그런데 윈도우 시스템 아이콘과 텍스트는 커지는데 Application 에서는 이게 자동으로 적용이 되지 않습니다 ㅠㅠ

개발자는 신경써야 할게 너무 많아요...

 

Qt의 경우에는 아래와 같이 main.cpp 에서 코드를 추가하게 되면 윈도우 DPI 배율에 따라 적용이 됩니다.

QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

 

High DPI 적용 안했을 때

 

High DPI 적용 했을 때

타이틀 바를 빼면 Qt Designer와 동일한 사이즈가 되었습니다.

 

그런데.... Designer의 위젯 사이즈 가로가 361 로 되어 있는데 화면의 1/5 정도가 차지하는군요.

전체 가로 해상도가 3840인데 361로 나누면 10배 정도가 됩니다.. 

결국 Designer 자체가 DPI 적용이 되어 있었던 것이고... 

조사해 보니 Qt 버그로 인해 150% 1.5배가 반올림 되어 200% DPI 적용이 되는 것이였습니다

 

결국 Application에서 DPI 옵션은 125%, 150%, 200% 배율에서는 동일한 윈도우 사이즈를 보이게 됩니다 ㅠㅠ

이래서는 Qt 가 제공하는 DPI 옵션은 사용이 어려우며 다른 방법을 알아보도록 하겠습니다.

 

아래 코드처럼 헤더에 QScreen을 include 선언하고,

사용하는 모니터의 스크린을 구해서, logicalDotsPerInch() 함수를 이용하여 스크린의 DPI를 얻습니다. 

 

이 값은 96이 100%이고 125%, 150%, 200% 일 때 값이 다르게 들어오게 됩니다.

그럼 96을 기준으로 나누어 주면 1.25, 1.5, 2 라는 실수형 배율을 구할 수 있게 됩니다.

#include <QScreen>
    QScreen *srn = QApplication::screens().at(config_info.Select_monitor); //사용모니터로 dpi계산.
    qreal dotsPerInch = (qreal)srn->logicalDotsPerInch();
    qreal dpiRatio = dotsPerInch / (qreal)96;

 

이렇게 구한 dpiRatio를 전체 위젯의 Geometry에 곱하여 새롭게 Geometry를 설정하게 되면 우리가 원하는 사이즈로 프로그램이 구동되게 됩니다.

    this->setGeometry(this->geometry().x(), this->geometry().y(), this->geometry().width()*dpiRatio, this->geometry().height()*dpiRatio);
    QRect rt1 = ui->pushButton->geometry();
    QRect rt2 = ui->pushButton_2->geometry();
    ui->pushButton->setGeometry(rt1.x()*dpiRatio, rt1.y()*dpiRatio, rt1.width()*dpiRatio, rt1.height()*dpiRatio);
    ui->pushButton_2->setGeometry(rt2.x()*dpiRatio, rt2.y()*dpiRatio, rt2.width()*dpiRatio, rt2.height()*dpiRatio);

 

추가적으로 각 위젯에 작업을 해야 하지만 이정도 노가다는 개발자에게 아무것도 아니죠 흐흐흐....

 

이상으로 DPI 적용에 대해 알아보았습니다.

728x90
반응형
Comments