如您所指出,paintEvent应该仅被覆盖。因此,一种方法是升级窗口小部件 您必须具有以下结构:
├── main.py
├── mywidget.py
└── UI designer
└── testUI.ui
在mywidget.py文件中,实现所需的类:
from pyside2 import QtCore, QtGui, QtWidgets
class Drawer(QtWidgets.QWidget):
def paintEvent(self, e):
"""
the method paintEvent() is called automatically
the QPainter class does all the low-level drawing
coded between its methods begin() and end()
"""
qp = QtGui.QPainter()
qp.begin(self)
self.drawGeometry(qp)
qp.end()
def drawGeometry(self, qp):
qp.setPen(QtGui.QPen(QtCore.Qt.green, 8, QtCore.Qt.DashLine))
qp.drawEllipse(40, 40, 400, 400)
然后,您必须使用Qt Designer打开.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>731</width>
<height>633</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QV@R_221_2419@Layout" name="verticalLayout">
<item>
<widget class="QGraphicsView" name="graphicsView">
<property name="minimumSize">
<size>
<width>0</width>
<height>200</height>
</size>
</property>
</widget>
</item>
<item>
<widget class="Drawer" name="widget" native="true">
<property name="minimumSize">
<size>
<width>0</width>
<height>250</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>300</height>
</size>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>731</width>
<height>23</height>
</rect>
</property>
</widget>
<widget class="QStatusBar" name="statusbar"/>
</widget>
<customwidgets>
<customwidget>
<class>Drawer</class>
<extends>QWidget</extends>
<header>mywidget</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>
另一方面,QUiLoader仅加载Qt默认提供的小部件,因此,如果要使用新的小部件,必须覆盖createWidget方法:
import os
import sys
from pyside2 import QtCore, QtGui, QtWidgets, QtUiTools
from mywidget import Drawer
class UiLoader(QtUiTools.QUiLoader):
def createWidget(self, className, parent=None, name=""):
if className == "Drawer":
widget = Drawer(parent)
widget.setObjectName(name)
return widget
return super(UiLoader, self).createWidget(className, parent, name)
class MainForm(QtCore.QObject):
def __init__(self, ui_file, parent=None):
super(MainForm, self).__init__(parent)
ui_file = QtCore.QFile(ui_file)
ui_file.open(QtCore.QFile.ReadOnly)
### Load UI file from Designer ###
loader = UiLoader()
self.ui_window = loader.load(ui_file)
ui_file.close()
self.ui_window.show()
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
app.setStyle("Fusion")
file = os.path.join(
os.path.dirname(os.path.realpath(__file__)), "./UI designer/testUI.ui"
)
form = MainForm(file)
sys.exit(app.exec_())