Search code examples
pythonpyqtpyqt5qt-designerpyuic

pyuic5 - Unknown C++ class: QfontDatabase


Used Qt Designer 5.9.5 to built a simple ui with a QFontComboBox. When I run pyuic5 it generates an error;

pyuic5 demoFontComboBox.ui -o demoFontComboBox.py
Unknown C++ class: QfontDatabase

The .ui file is;

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>Dialog</class>
 <widget class="QDialog" name="Dialog">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>500</width>
    <height>240</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Dialog</string>
  </property>
  <widget class="QLabel" name="label">
   <property name="geometry">
    <rect>
     <x>30</x>
     <y>50</y>
     <width>81</width>
     <height>17</height>
    </rect>
   </property>
   <property name="text">
    <string>Select font</string>
   </property>
  </widget>
  <widget class="QLabel" name="label_2">
   <property name="geometry">
    <rect>
     <x>30</x>
     <y>90</y>
     <width>81</width>
     <height>17</height>
    </rect>
   </property>
   <property name="text">
    <string>Type text</string>
   </property>
  </widget>
  <widget class="QFontComboBox" name="fontSelect">
   <property name="geometry">
    <rect>
     <x>120</x>
     <y>40</y>
     <width>291</width>
     <height>25</height>
    </rect>
   </property>
   <property name="writingSystem">
    <enum>QFontDatabase::Any</enum>
   </property>
  </widget>
  <widget class="QTextEdit" name="textEdit">
   <property name="geometry">
    <rect>
     <x>120</x>
     <y>80</y>
     <width>291</width>
     <height>101</height>
    </rect>
   </property>
  </widget>
 </widget>
 <resources/>
 <connections/>
</ui>

A partial .py file is generated as follows;

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'demoFontComboBox.ui'
#
# Created by: PyQt5 UI code generator 5.9.2
#
# WARNING! All changes made in this file will be lost!

from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_Dialog(object):
    def setupUi(self, Dialog):
        Dialog.setObjectName("Dialog")
        Dialog.resize(500, 240)
        self.label = QtWidgets.QLabel(Dialog)
        self.label.setGeometry(QtCore.QRect(30, 50, 81, 17))
        self.label.setObjectName("label")
        self.label_2 = QtWidgets.QLabel(Dialog)
        self.label_2.setGeometry(QtCore.QRect(30, 90, 81, 17))
        self.label_2.setObjectName("label_2")
        self.fontSelect = QtWidgets.QFontComboBox(Dialog)
        self.fontSelect.setGeometry(QtCore.QRect(120, 40, 291, 25))

The generated code appears to be missing a retranslatedUi() function declaration and invocation.

pyuic5 has successfully generated files from ui's with QLineEdit, QButton, QRadioButton before and after trying the above ui example.


Solution

  • It seems that it is a PyQt5 bug that does not recognize the QFontDatabase class, for the moment the workaround is to eliminate the following lines:

    <property name="writingSystem">
     <enum>QFontDatabase::Any</enum>
    </property>
    

    So executing the command:

    pyuic5 demoFontComboBox.ui -o demoFontComboBox.py -x
    

    You get the following:

    # -*- coding: utf-8 -*-
    
    # Form implementation generated from reading ui file 'demoFontComboBox.ui'
    #
    # Created by: PyQt5 UI code generator 5.12.1
    #
    # WARNING! All changes made in this file will be lost!
    
    from PyQt5 import QtCore, QtGui, QtWidgets
    
    
    class Ui_Dialog(object):
        def setupUi(self, Dialog):
            Dialog.setObjectName("Dialog")
            Dialog.resize(500, 240)
            self.label = QtWidgets.QLabel(Dialog)
            self.label.setGeometry(QtCore.QRect(30, 50, 81, 17))
            self.label.setObjectName("label")
            self.label_2 = QtWidgets.QLabel(Dialog)
            self.label_2.setGeometry(QtCore.QRect(30, 90, 81, 17))
            self.label_2.setObjectName("label_2")
            self.fontSelect = QtWidgets.QFontComboBox(Dialog)
            self.fontSelect.setGeometry(QtCore.QRect(120, 40, 291, 25))
            self.fontSelect.setObjectName("fontSelect")
            self.textEdit = QtWidgets.QTextEdit(Dialog)
            self.textEdit.setGeometry(QtCore.QRect(120, 80, 291, 101))
            self.textEdit.setObjectName("textEdit")
    
            self.retranslateUi(Dialog)
            QtCore.QMetaObject.connectSlotsByName(Dialog)
    
        def retranslateUi(self, Dialog):
            _translate = QtCore.QCoreApplication.translate
            Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
            self.label.setText(_translate("Dialog", "Select font"))
            self.label_2.setText(_translate("Dialog", "Type text"))
    
    
    
    
    if __name__ == "__main__":
        import sys
        app = QtWidgets.QApplication(sys.argv)
        Dialog = QtWidgets.QDialog()
        ui = Ui_Dialog()
        ui.setupUi(Dialog)
        Dialog.show()
        sys.exit(app.exec_())
    

    Still working on a patch for pyqt5.

    The solution is to register the QFontDatabase class in PyQt5/uic/Compiler/qtproxies.py:

    # ...
    class QtGui(ProxyNamespace):
        class QIcon(ProxyClass):
            class fromTheme(ProxyClass): pass
    
        class QConicalGradient(ProxyClass): pass
        class QLinearGradient(ProxyClass): pass
        class QRadialGradient(ProxyClass): pass
        class QBrush(ProxyClass): pass
        class QPainter(ProxyClass): pass
        class QPalette(ProxyClass): pass
        class QFont(ProxyClass): pass
        class QFontDatabase(ProxyClass): pass # <--- add this line
    # ...