【PyQt】QLabel의 사이즈 변화에 맞추어 문자 사이즈를 자동적으로 변경한다【Qt】
소개
Linux의 X상에서 약간의 앱을 만들고 싶을 때 Pyqt는 편리하네요. python과 python-pyqt5를 넣으면 끝이지만 win에서도 linux에서도 코드 변경없이 같은 방식으로 움직이거나 Qt의 신호 슬롯 작법도 C/C++라고 고문하고 싶은 문자를 치는 느낌이 없다. 그런데 (웃음)
지금 만드는 앱은 그리드 레이아웃을 사용하여 윈도우의 크기를 변경하면 그리드 레이아웃에 배치한 QLabel의 크기도 변화합니다. 하지만 QLabel 안의 캐릭터 라인의 사이즈는 변화하지 않고, WPF의 ViewBox 같은 것이 없을까-라고 조사하는 것도 없을 것 같고, 영어의 QA 사이트의 것을 참고로 해 만들었습니다. ( 앱의 완제품은 이런 느낌 )
QLabel의 문자 크기를 QLabel 프레임의 크기에 따라 변경
QLabel 안의 문자의 사이즈를 QLabel의 테두리의 사이즈에 따라서 변화시키는 방법은, 얽히 말하면 QLabel를 계승해 resizeEvent를 오버라이드(override) 해 거기서 폰트 사이즈를 가변해 준다고 하는 것.
#! /usr/bin/python3
# -*- coding: utf-8 -*-
from PyQt5 import QtCore
from PyQt5.QtGui import QFont
from PyQt5.QtWidgets import QApplication, QWidget, QGridLayout, QLabel, QSizePolicy
import sys
class QCustomLabel(QLabel):
def __init__(self, text):
super(QCustomLabel, self).__init__(text)
self._font = QFont()
self.setFont(self._font)
self.setAlignment(QtCore.Qt.AlignVCenter | QtCore.Qt.AlignHCenter)
self.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored)
self._fontScale = 1.0
def setFontFamily(self, face):
self._font.setFamily(face)
def setFontScale(self, scale):
self._fontScale = scale
def resizeEvent(self, evt):
width = self.size().width() / len(self.text())
height = self.size().height()
baseSize = 0
if width > height:
baseSize = height
else:
baseSize = width
self._font.setPixelSize(baseSize * self._fontScale)
self.setFont(self._font)
if __name__ == '__main__':
app = QApplication(sys.argv)
window = QWidget()
style = 'QWidget{background-color:#1976D2;} QLabel{color:#FFFFFF; background-color:#2196F3; border-color:#FF9800;}'
app.setStyleSheet(style)
layout = QGridLayout()
layout.setContentsMargins(5, 5, 5, 5)
labelA = QCustomLabel('あ')
labelA.setFontFamily('源ノ角ゴシック Code JP M')
layout.addWidget(labelA, 0, 0)
labelB = QCustomLabel('あ')
labelB.setFontFamily('源ノ角ゴシック Code JP M')
labelB.setFontScale(2)
layout.addWidget(labelB, 0, 1)
window.setLayout(layout)
window.resize(300, 200)
window.show()
sys.exit(app.exec_())
해설
def __init__(self, text):
super(QCustomLabel, self).__init__(text)
self._font = QFont()
self.setFont(self._font)
self.setAlignment(QtCore.Qt.AlignVCenter | QtCore.Qt.AlignHCenter)
self.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored)
self._fontScale = 1.0
setSizePolicy로 ignored를 지정하는 것이 첫 번째 미소. 초기화시에 들어가는 폰트 사이즈와 문자수가 Qlabel 자체의 최소 사이즈가 되는 것을 막습니다.
def setFontFamily(self, face):
self._font.setFamily(face)
def setFontScale(self, scale):
self._fontScale = scale
setFontFamily는 QLabel의 폰트를 바꾸는 것이 번거로웠기 때문에 만든 것.
setFontScale은 resize시에 결정한 사이즈에 곱하는 계수.
def resizeEvent(self, evt):
width = self.size().width() / len(self.text())
height = self.size().height()
baseSize = 0
if width > height:
baseSize = height
else:
baseSize = width
self._font.setPixelSize(baseSize * self._fontScale)
self.setFont(self._font)
위젯의 사이즈가 변경되면(자) 이 이벤트가 호출되므로, 그 때의 사이즈를 조사해 폰트 사이즈를 세트 한다.
width측은 단순히 문자수로 나누어 한 문자당의 폭을 산출하고 있는데, 폰트에 따라서는 정확하지 않게 되므로 이 근처는 QFontMetrics로 취해 계산하는 것 같지만, 조금 계산이 다소 어렵기 때문에 단단히 접었습니다…
로, 어느 쪽인가 사이즈가 작은 쪽이 세트 해야 하는 폰트의 pixelSize가 된다. self._fontScale은 덤 기능의 폰트 크기의 변경에 대응한 것. 1이라면 아무것도 하지 않는다.
if __name__ == '__main__':
app = QApplication(sys.argv)
window = QWidget()
style = 'QWidget{background-color:#1976D2;} QLabel{color:#FFFFFF; background-color:#2196F3; border-color:#FF9800;}'
app.setStyleSheet(style)
layout = QGridLayout()
layout.setContentsMargins(5, 5, 5, 5)
labelA = QCustomLabel('あ')
labelA.setFontFamily('源ノ角ゴシック Code JP M')
layout.addWidget(labelA, 0, 0)
labelB = QCustomLabel('あ')
labelB.setFontFamily('源ノ角ゴシック Code JP M')
labelB.setFontScale(2)
layout.addWidget(labelB, 0, 1)
window.setLayout(layout)
window.resize(300, 200)
window.show()
sys.exit(app.exec_())
그리고는, 알기 쉽도록 setStyleSheet로 조금 색을 바꾸어, 메인 window 배경과 label의 배경을 분리, 그리드 레이아웃의 컨텐츠 사이에 마진 열어 메인 window의 배경이 보이게 하고 있습니다.
첫 번째 왼쪽에 표시하는 "아"는 x1배, 두 번째 "아"는 x2배로 표시하고 있습니다.
마지막입니다만, 안의 모든 위젯의 setSizePolicy가 Ignore이므로 윈도우 사이즈를 명시해 지정하지 않으면 최초 작게 표시되어 버리므로, 300x200을 지정하고 있습니다.
결과
덧붙여서 QPushButton라든지에서도 응용 가능할 것입니다.
참고
Automatically resizing label text in Qt - strange behaviour
Reference
이 문제에 관하여(【PyQt】QLabel의 사이즈 변화에 맞추어 문자 사이즈를 자동적으로 변경한다【Qt】), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/marksard/items/7afeb3ab3ffa61ae8d27
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
QLabel 안의 문자의 사이즈를 QLabel의 테두리의 사이즈에 따라서 변화시키는 방법은, 얽히 말하면 QLabel를 계승해 resizeEvent를 오버라이드(override) 해 거기서 폰트 사이즈를 가변해 준다고 하는 것.
#! /usr/bin/python3
# -*- coding: utf-8 -*-
from PyQt5 import QtCore
from PyQt5.QtGui import QFont
from PyQt5.QtWidgets import QApplication, QWidget, QGridLayout, QLabel, QSizePolicy
import sys
class QCustomLabel(QLabel):
def __init__(self, text):
super(QCustomLabel, self).__init__(text)
self._font = QFont()
self.setFont(self._font)
self.setAlignment(QtCore.Qt.AlignVCenter | QtCore.Qt.AlignHCenter)
self.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored)
self._fontScale = 1.0
def setFontFamily(self, face):
self._font.setFamily(face)
def setFontScale(self, scale):
self._fontScale = scale
def resizeEvent(self, evt):
width = self.size().width() / len(self.text())
height = self.size().height()
baseSize = 0
if width > height:
baseSize = height
else:
baseSize = width
self._font.setPixelSize(baseSize * self._fontScale)
self.setFont(self._font)
if __name__ == '__main__':
app = QApplication(sys.argv)
window = QWidget()
style = 'QWidget{background-color:#1976D2;} QLabel{color:#FFFFFF; background-color:#2196F3; border-color:#FF9800;}'
app.setStyleSheet(style)
layout = QGridLayout()
layout.setContentsMargins(5, 5, 5, 5)
labelA = QCustomLabel('あ')
labelA.setFontFamily('源ノ角ゴシック Code JP M')
layout.addWidget(labelA, 0, 0)
labelB = QCustomLabel('あ')
labelB.setFontFamily('源ノ角ゴシック Code JP M')
labelB.setFontScale(2)
layout.addWidget(labelB, 0, 1)
window.setLayout(layout)
window.resize(300, 200)
window.show()
sys.exit(app.exec_())
해설
def __init__(self, text):
super(QCustomLabel, self).__init__(text)
self._font = QFont()
self.setFont(self._font)
self.setAlignment(QtCore.Qt.AlignVCenter | QtCore.Qt.AlignHCenter)
self.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored)
self._fontScale = 1.0
setSizePolicy로 ignored를 지정하는 것이 첫 번째 미소. 초기화시에 들어가는 폰트 사이즈와 문자수가 Qlabel 자체의 최소 사이즈가 되는 것을 막습니다.
def setFontFamily(self, face):
self._font.setFamily(face)
def setFontScale(self, scale):
self._fontScale = scale
setFontFamily는 QLabel의 폰트를 바꾸는 것이 번거로웠기 때문에 만든 것.
setFontScale은 resize시에 결정한 사이즈에 곱하는 계수.
def resizeEvent(self, evt):
width = self.size().width() / len(self.text())
height = self.size().height()
baseSize = 0
if width > height:
baseSize = height
else:
baseSize = width
self._font.setPixelSize(baseSize * self._fontScale)
self.setFont(self._font)
위젯의 사이즈가 변경되면(자) 이 이벤트가 호출되므로, 그 때의 사이즈를 조사해 폰트 사이즈를 세트 한다.
width측은 단순히 문자수로 나누어 한 문자당의 폭을 산출하고 있는데, 폰트에 따라서는 정확하지 않게 되므로 이 근처는 QFontMetrics로 취해 계산하는 것 같지만, 조금 계산이 다소 어렵기 때문에 단단히 접었습니다…
로, 어느 쪽인가 사이즈가 작은 쪽이 세트 해야 하는 폰트의 pixelSize가 된다. self._fontScale은 덤 기능의 폰트 크기의 변경에 대응한 것. 1이라면 아무것도 하지 않는다.
if __name__ == '__main__':
app = QApplication(sys.argv)
window = QWidget()
style = 'QWidget{background-color:#1976D2;} QLabel{color:#FFFFFF; background-color:#2196F3; border-color:#FF9800;}'
app.setStyleSheet(style)
layout = QGridLayout()
layout.setContentsMargins(5, 5, 5, 5)
labelA = QCustomLabel('あ')
labelA.setFontFamily('源ノ角ゴシック Code JP M')
layout.addWidget(labelA, 0, 0)
labelB = QCustomLabel('あ')
labelB.setFontFamily('源ノ角ゴシック Code JP M')
labelB.setFontScale(2)
layout.addWidget(labelB, 0, 1)
window.setLayout(layout)
window.resize(300, 200)
window.show()
sys.exit(app.exec_())
그리고는, 알기 쉽도록 setStyleSheet로 조금 색을 바꾸어, 메인 window 배경과 label의 배경을 분리, 그리드 레이아웃의 컨텐츠 사이에 마진 열어 메인 window의 배경이 보이게 하고 있습니다.
첫 번째 왼쪽에 표시하는 "아"는 x1배, 두 번째 "아"는 x2배로 표시하고 있습니다.
마지막입니다만, 안의 모든 위젯의 setSizePolicy가 Ignore이므로 윈도우 사이즈를 명시해 지정하지 않으면 최초 작게 표시되어 버리므로, 300x200을 지정하고 있습니다.
결과
덧붙여서 QPushButton라든지에서도 응용 가능할 것입니다.
참고
Automatically resizing label text in Qt - strange behaviour
Reference
이 문제에 관하여(【PyQt】QLabel의 사이즈 변화에 맞추어 문자 사이즈를 자동적으로 변경한다【Qt】), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/marksard/items/7afeb3ab3ffa61ae8d27
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Automatically resizing label text in Qt - strange behaviour
Reference
이 문제에 관하여(【PyQt】QLabel의 사이즈 변화에 맞추어 문자 사이즈를 자동적으로 변경한다【Qt】), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/marksard/items/7afeb3ab3ffa61ae8d27텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)