본문 바로가기
놀기/Qt

[Qt] Widget 크기에 맞게 폰트 조절하기 (feat. QLabel을 QPixmap으로 변환)

by Hi~ 2023. 8. 27.

폰트 크기를 화면에 맞게 자동으로 조정해야 할 일이 있는데, 폰트 크기를 지정해서 간단히 해결되면 문제가 없지만, 가변적이면 귀찮은 문제다. 여러 방법으로 해결할 수 있는 문제인데, 

 

Widget 크기를 계산해서 폰트 크기를 직접 바꾸는 방법이 정식이다. 예제는 github에서 찾을 수 있다. (게시물 마지막 부분 참조)

 

나는 트릭이지만 QLabel에 글자를 쓴 후에 QPixmap으로 변경하여 scale 하는 방법을 사용하려 한다. 경우에 따라 폰트의 세로 크기만 조정이 필요할 수 있으니 나쁜 방법은 아닐 것 같다.

 

1) 글자를 쓸 QLabel을 만든다.

- m_labelMsg를 아래와 같이 설정한다.

- 수평/수직 방향으로 중앙 정렬을 하고

- 여러줄을 사용할 수 있게 setWordWrap()을 설정한다.

- 배경이 투명해야 배경과 어울리게 되니 setStyleSheet()로 설정한다.

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    m_pixmapBG.load(":/images/test.png");
    m_labelMsg.setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
    m_labelMsg.setWordWrap(true);
    m_labelMsg.setStyleSheet("background-color: rgba(0,0,0,0%);color:white");
    m_labelMsg.hide();
}

 

 

 

2) 문자열을 QLabel에 쓴 후, grab() 함수를 사용하여 QPixmap으로 만든다.

- 여기서는 메인화면에 그렸지만, 메인화면도 Widget이니, 그리고 다른 Widget도 QPixmap을 올릴 수 있고...

- 먼저, m_labelMsg의 폰트 설정을 한다. scale을 할 예정이니 가능한 폰트 크기를 크게 해서 이미지가 깨지지 않게 한다.

- 또한, 문자열을 화면에 썼을 때의 크기를 알아야 하므로 QFontMetrics를 사용하여 크기를 확인한다.

- 확인한 크기를 기반으로 QLabel의 크기를 조정하고 setText()를 사용하여 문자열을 쓴다. 크기는 임의로 한 것이고 각자 조건에 배율과 크기를 고려하여 설정하면 된다.

- 마지막으로 grab()을 사용하여 QPixmap을 만든다.

- 참고로 pixmap() 함수도 있는데, 사용할 수 없다. 이 함수를 사용하려면 QLabel에 pixmap이 올라간 상태여야 한다. 하지만 여기서는 setText()로 문자열을 쓰기 때문에 조건에 맞지 않는다.

void MainWindow::on_btnGetPixmap_clicked()
{
    QFont f;
    f.setPointSize(50);

    QString sz("How many pixels wide is this text?\n우리나라대한민국\nHI~~~~~~~~~\nByeBye~~~~~");
    m_labelMsg.setFont(f);
    QFontMetrics fm(m_labelMsg.font());
    int textWidthInPixels = fm.horizontalAdvance(sz);
    int textHeightInPixels = fm.height();

    m_labelMsg.setText(sz);
    m_labelMsg.setFixedWidth(textWidthInPixels);
    m_labelMsg.setFixedHeight(textHeightInPixels*10);

    m_pixmapMsg = m_labelMsg.grab();
    update();
}

 

 

3) Widget에 맞게 그리는 것은 paintEvent()를 사용해서 처리한다.

- 다른 방법이 있겠지만, 내가 필요한 방법은 paintEvent()에서 사용하는 것이다.

- 먼저, 배경을 그리고

- 그위에 위에서 만든 m_pixmapMsg를 그린다. QLabel의 배경을 투명하게 했기 때문에 배경을 가지지 않게 된다. 

void MainWindow::paintEvent(QPaintEvent *event)
{
    int w = geometry().width();
    int h = geometry().height();

    QPainter p;
    p.begin(this);

    p.drawPixmap(0, 0, w, h, m_pixmapBG);
    if (false == m_pixmapMsg.isNull()) {
        p.drawPixmap(0, 0, w, h, m_pixmapMsg.scaled(w, h, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
    }

    p.end();
}

 

 

 

4) 실행하면 아래와 같이 된다.

https://youtu.be/oax5jawPBwA

 

 

5) 소스코드

bmTestFontSize.tar.gz
0.38MB

 

 

 


위에서 말한 실제 폰트 사이즈를 변경하는 방법이다. 소스가 간결하고 다운로드하여 컴파일하면 잘 돌아간다.

 

DynamicFontSizeWidgets

Dynamic font size QPushButton and QLabel

Implemented dynamic font size according to defined widget size and accounts for QLabel new lines. Tested with Qt5/Android, Qt5/Linux and Qt4. Tested with QSizePolicy::MinimumExpanding and QSizePolicy::Fixed.

 

https://github.com/jonaias/DynamicFontSizeWidgets

 

GitHub - jonaias/DynamicFontSizeWidgets: Dynamic font size QPushButton and QLabel

Dynamic font size QPushButton and QLabel. Contribute to jonaias/DynamicFontSizeWidgets development by creating an account on GitHub.

github.com

 

빌드해 보면 아래와 같이 실행된다.

https://youtu.be/d7--OQk1bE0

 

 

댓글