where do I write the class for a single promoted QWidget from Qt designer

末鹿安然 提交于 2020-04-16 05:51:10

问题


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)


回答1:


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

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


来源:https://stackoverflow.com/questions/60782496/where-do-i-write-the-class-for-a-single-promoted-qwidget-from-qt-designer

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!