Кастомные шрифты и PyQt5
Пишу проект на PyQt5, применяя при этом кастомный шрифт (Comfortaa из Google Fonts). Естественно, чтобы всё хорошо работало на других компьютерах, решил зашить шрифт в программу.
Первоначальный вариант выглядел так:
QFontDatabase.addApplicationFont('Fonts/Comfortaa-VariableFont_wght.ttf')
Это прописано в методе инициализации основного окна (других не имеется). Была только одна проблема - на втором компьютере ничего не работало.
Другой вариант - добавить шрифт в файл ресурсов, и после на него сослаться в основной программе. Файл ресурсов (его я после сконвертировал в файл.py):
<RCC>
<qresource prefix="icons">
<file>keyboard_backspace_FILL0_wght500_GRAD-25_opsz48.png</file>
<file>settings_FILL1_wght300_GRAD0_opsz48.png</file>
</qresource>
<qresource prefix="font">
<file>Comfortaa-VariableFont_wght.ttf</file>
</qresource>
</RCC>
Код из метода инициализации:
QFontDatabase.addApplicationFont(':/font/Comfortaa-VariableFont_wght.ttf')
И код из самого конца программы (отображение окна):
app = QApplication(sys.argv)
app.setFont(QFont('Comfortaa', 8))
Итог просто шедевральный - шрифт после преобразования в .exe отображается только в тексте, прописанном в одном из табвиджетов, но при этом не отображается ни в комбо боксе, ни на кнопках - короче говоря, больше нигде.
Что я делаю не так? Как это исправить?
P.S. Пример кода (здесь даже в табвиджете ничего не работает)
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtGui import QFontDatabase
import resources_rc
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(942, 600)
MainWindow.setStyleSheet("QMainWindow {\n"
" font-family: Comfortaa;\n"
"}")
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.horizontalLayout = QtWidgets.QHBoxLayout(self.centralwidget)
self.horizontalLayout.setObjectName("horizontalLayout")
self.pushButton = QtWidgets.QPushButton(self.centralwidget)
font = QtGui.QFont()
font.setFamily("Comfortaa")
self.pushButton.setFont(font)
self.pushButton.setObjectName("pushButton")
self.horizontalLayout.addWidget(self.pushButton)
self.comboBox = QtWidgets.QComboBox(self.centralwidget)
font = QtGui.QFont()
font.setFamily("Comfortaa")
self.comboBox.setFont(font)
self.comboBox.setObjectName("comboBox")
self.comboBox.addItem("")
self.comboBox.addItem("")
self.horizontalLayout.addWidget(self.comboBox)
self.tabWidget = QtWidgets.QTabWidget(self.centralwidget)
self.tabWidget.setObjectName("tabWidget")
self.tab = QtWidgets.QWidget()
self.tab.setObjectName("tab")
self.gridLayout = QtWidgets.QGridLayout(self.tab)
self.gridLayout.setObjectName("gridLayout")
self.label = QtWidgets.QLabel(self.tab)
font = QtGui.QFont()
font.setFamily("Comfortaa")
self.label.setFont(font)
self.label.setObjectName("label")
self.gridLayout.addWidget(self.label, 0, 0, 1, 1)
self.tabWidget.addTab(self.tab, "")
self.tab_2 = QtWidgets.QWidget()
self.tab_2.setObjectName("tab_2")
self.tabWidget.addTab(self.tab_2, "")
self.horizontalLayout.addWidget(self.tabWidget)
MainWindow.setCentralWidget(self.centralwidget)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
QFontDatabase.addApplicationFont(':/font/Comfortaa-VariableFont_wght.ttf')
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.pushButton.setText(_translate("MainWindow", "кнопка"))
self.comboBox.setItemText(0, _translate("MainWindow", "раз"))
self.comboBox.setItemText(1, _translate("MainWindow", "два"))
self.label.setText(_translate("MainWindow", "Оперативная информация, которая представляет политический, социальный или экономический\n"
"интерес для аудитории в своей свежести, то есть сообщения о событиях, произошедших недавно\n"
"или происходящих в данный момент. Также новостями называют программы на телевидении и\n"
"радио, а в печатной прессе или на веб-сайтах - сводки новостей, в специальной рубрике в газете."))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), _translate("MainWindow", "Tab 1"))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2), _translate("MainWindow", "Tab 2"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
main.exe создавал с помощью pyinstaller
Ответы (1 шт):
Создал каталоги icons и font. Поместил туда изображения и шрифты.
Создал файл ресурсов q1506816.qrc:
<RCC>
<qresource prefix="Images">
<file>icons/back.png</file>
<file>icons/exit.png</file>
</qresource>
<qresource prefix="Fonts">
<file>font/fontawesome-webfont.ttf</file>
<file>font/Roboto-Regular.ttf</file>
<file>font/Roboto-Thin.ttf</file>
<file>font/segoeui.ttf</file>
<file>font/segoeuib.ttf</file>
</qresource>
</RCC>
Сконвертировал q1506816.qrc в q1506816_rc.py:
pyrcc5 q1506816.qrc -o q1506816_rc.py
Создал файл q1506816.py:
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.Qt import *
import q1506816_rc # !!! +++ q1506816_rc.py
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(700, 600)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.horizontalLayout = QtWidgets.QHBoxLayout(self.centralwidget)
self.horizontalLayout.setObjectName("horizontalLayout")
self.pushButton = QtWidgets.QPushButton(self.centralwidget)
self.pushButton.setObjectName("pushButton")
self.horizontalLayout.addWidget(self.pushButton)
self.comboBox = QtWidgets.QComboBox(self.centralwidget)
self.comboBox.setObjectName("comboBox")
self.comboBox.addItem("")
self.comboBox.addItem("")
self.horizontalLayout.addWidget(self.comboBox)
self.tabWidget = QtWidgets.QTabWidget(self.centralwidget)
self.tabWidget.setObjectName("tabWidget")
self.tab = QtWidgets.QWidget()
self.tab.setObjectName("tab")
self.gridLayout = QtWidgets.QGridLayout(self.tab)
self.gridLayout.setObjectName("gridLayout")
self.label = QtWidgets.QLabel(self.tab)
self.label.setObjectName("label")
self.gridLayout.addWidget(self.label, 0, 0, 1, 1)
self.tabWidget.addTab(self.tab, "")
self.tab_2 = QtWidgets.QWidget()
self.tab_2.setObjectName("tab_2")
self.tabWidget.addTab(self.tab_2, "")
self.horizontalLayout.addWidget(self.tabWidget)
MainWindow.setCentralWidget(self.centralwidget)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.pushButton.setText(_translate("MainWindow", "Кнопка"))
self.comboBox.setItemText(0, _translate("MainWindow", "Раз"))
self.comboBox.setItemText(1, _translate("MainWindow", "Два"))
#
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab),
_translate("MainWindow", "Tab 1"))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2),
_translate("MainWindow", "Tab 2"))
class MainWindow(QMainWindow, Ui_MainWindow):
def __init__(self):
super().__init__()
self.setupUi(self)
self.tab_2.setStyleSheet(
# -------------------------------> vvvvvvvvvvvvvvvvvvvvvvv <--------------
"background-image: url(:/Images/icons/back.png);")
# ----------------------------------------> ^^^^^ <-----------------------
icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap(":/Images/icons/exit.png"))
# -------------------------------------------> ^^^^^ <--------------------
self.pushButton.setIcon(icon)
self.label.setText('Stack Overflow Tab 1 , Tab 2 Раз Два')
font = QFont()
font.setFamily("Roboto Thin") # !!! +++ Roboto Thin
font.setPointSize(27)
self.label.setFont(font)
self.label.setWordWrap(True)
self.label_2 = QtWidgets.QLabel(self.tab)
self.label_2.setWordWrap(True)
self.label_2.setText('Stack Overflow Tab 1 , Tab 2 Раз Два')
font_2 = QFont()
font_2.setFamily("Roboto Regular") # !!! +++ Roboto Regular
font_2.setPointSize(27)
self.label_2.setFont(font_2)
self.gridLayout.addWidget(self.label_2, 1, 0, 1, 1)
font = QtGui.QFont(fontName) # !!! + FontAwesome
font.setPointSize(32)
self.pushButton.setFont(font)
self.pushButton.setText(chr(0xf101)) # !!! + chr(0xf101)
self.comboBox.setFont(font_2) # !!! +++ Roboto Regular
self.tabWidget.setFont(font_2) # !!! +++ Roboto Regular
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
# !!! +++ vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
QtGui.QFontDatabase.addApplicationFont(':/Fonts/font/segoeui.ttf')
fontId = QtGui.QFontDatabase.addApplicationFont(
':/Fonts/font/fontawesome-webfont.ttf') # !!!
#print(f'\nfontId = {fontId} \n')
fontName = QFontDatabase.applicationFontFamilies(fontId)[0]
print(f'fontName = {fontName} \n')
QtGui.QFontDatabase.addApplicationFont(':/Fonts/font/segoeuib.ttf')
QtGui.QFontDatabase.addApplicationFont(':/Fonts/font/Roboto-Regular.ttf') # !!!
QtGui.QFontDatabase.addApplicationFont(':/Fonts/font/Roboto-Thin.ttf') # !!!
# +++ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
w = MainWindow()
w.show()
sys.exit(app.exec_())
Преобразовал q1506816.py в q1506816.exe:
pyinstaller -F -w q1506816.py
Запустил q1506816.exe
Все работает.



