4

I read, test and understand a lot of examples for usage of QWidgets from Qt designer, which are promoted to PyQt5. Nevertheless I am not able to deal with a simple example for my own.

Beneath I show my code, which is not working and try to explain.

in Qt desginer i create a simple QMainWindow, named standardized as MainWindow

Within I create a single label QLabel. This I promote to class "neuLabel" and name it labelqt. The window with, Add , the header neulabel.h and promote --> everything is fine.

I understand, that I have to write code for the class neuLabel. But: WHERE to do it?

With very simple example I tried it like this:

from PyQt5 import QtWidgets, uic
import sys
uifile_1 = 'testpromote.ui'
form_1, base_1 = uic.loadUiType(uifile_1)
class neuLabel(QLabel, QPixmap):
    def __init__(self,title,pixmap,parent):
    super().__init__(title,parent)
    self.setAcceptDrops(True)
def mousePressEvent(self, e):
    QLabel.mousePressEvent(self, e)
    if e.button() == QtCore.Qt.LeftButton:
        print('press')
class myApp(base_1, form_1):
    def __init__(self):
        super(base_1,self).__init__()
        self.setupUi(self)
if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = myApp()   #Dialog()
    ex.show()
sys.exit(app.exec_())

The error is like this

Traceback (most recent call last):
  File "/home/jf/PycharmProjects/myMuhaInp/testpromote.py", line 5, in <module>
    form_1, base_1 = uic.loadUiType(uifile_1)
  File "/usr/lib/python3/dist-packages/PyQt5/uic/__init__.py", line 201, in loadUiType
    exec(code_string.getvalue(), ui_globals)
  File "<string>", line 37, in <module>
ModuleNotFoundError: No module named 'neulabel'

I really don't understand, WHERE to code the class neulabel (and I really tried a lot of examples. (In no example, I found, is the promotion of a single QWidget)

0

1 Answer 1

7

Before all your code has an error: Why do you need a class that inherits from QLabel and QPixmap? I don't see the point, a QLabel uses a QPixmap(composition), a QLabel is not a QPixmap(inherency).

For a widget to be promoted it must have the following rules (I did not find them in the docs):

  • The constructor of the widget must have a single parameter and must be the parent.

  • The class must not be in the same file where it is used since it can create a circular import.

  • The widget promotion form asks for 2 data:

    1. Promoted class name which must be the name of the class.
    2. Header file which must be the location of the file where the class is (in C++ by custom rule the name of the file is the same name of the class but with lowercase letters, but in python it does not comply).

    For example if "FooClass" is placed as Promoted class name and "a/b/c" or "a.b.c" is placed in Header file it will be translated to from a.b.c import Foo so verify that this is correct.

Example:

Considering the above, the simplest implementation is to create a .py where the class to be promoted is:

neulabel.py

from PyQt5 import QtCore, QtWidgets


class NeuLabel(QtWidgets.QLabel):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setAcceptDrops(True)

    def mousePressEvent(self, e):
        super().mousePressEvent(e)
        if e.button() == QtCore.Qt.LeftButton:
            print("press")

Then in the .ui you must fill in the following in the form, press the "Add" button and then the "Promote" button

enter image description here

Generating the following .ui:

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>800</width>
    <height>600</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <widget class="QWidget" name="centralwidget">
   <widget class="NeuLabel" name="label">
    <property name="geometry">
     <rect>
      <x>120</x>
      <y>160</y>
      <width>251</width>
      <height>191</height>
     </rect>
    </property>
    <property name="text">
     <string>TextLabel</string>
    </property>
   </widget>
  </widget>
  <widget class="QMenuBar" name="menubar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>800</width>
     <height>26</height>
    </rect>
   </property>
  </widget>
  <widget class="QStatusBar" name="statusbar"/>
 </widget>
 <customwidgets>
  <customwidget>
   <class>NeuLabel</class>
   <extends>QLabel</extends>
   <header>neulabel</header>
  </customwidget>
 </customwidgets>
 <resources/>
 <connections/>
</ui>

Then used in the main file:

import os
import sys

from PyQt5 import QtWidgets, uic

CURRENT_DIR = os.path.dirname(os.path.realpath(__file__))

uifile_1 = os.path.join(CURRENT_DIR, "testpromote.ui")
form_1, base_1 = uic.loadUiType(uifile_1)


class myApp(base_1, form_1):
    def __init__(self):
        super(base_1, self).__init__()
        self.setupUi(self)


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    ex = myApp()
    ex.show()
    sys.exit(app.exec_())
├── main.py
├── neulabel.py
└── testpromote.ui
4
  • Hello @eyllanesc. What about when the python file containing the custom class is not in the same folder than the main.py, nor the testpromote.ui. I have a code structure where the main.py is alone in src with the other files in subfolders, but even if I enter /pathTo.py in the .h header file name, It doesn't seem to work. Any idea?
    – PyThagoras
    Commented Mar 18, 2021 at 13:01
  • Nevermind, it does work if you enter the correct path from the launched .py file. Be mindful of the capitalized letters.
    – PyThagoras
    Commented Mar 18, 2021 at 15:12
  • if your .ui file is in relativepath\repo\app\app.py and a class you want to promote in relativepath\repo\lib\custom_classes.py , is it possible to specify that header file with ..\..\lib\custom_classes.py or something? hitting import errors ...
    – 10mjg
    Commented Jan 14, 2022 at 17:39
  • this worked for me: stackoverflow.com/questions/19622014/…
    – 10mjg
    Commented Jan 14, 2022 at 17:59

Not the answer you're looking for? Browse other questions tagged or ask your own question.