Python PySide2在设计器创建的小部件上绘制
此问题与Win10和Python 3.6.6上的VS代码有关。我对Python和PySide2都是新手 我在StackOverflow上读了很多关于这个的主题,可能这是另一个主题的重复,但我无法绘制我的小部件 我知道widget对象的paintEvent()必须以某种方式重写。大多数示例都在主窗口上进行了一些绘制,但我无法将其从ui.file传输到widget上 我在.py文件中创建了两个类:MainForm和Drawer。MainForm包含UI的实现,我正在尝试绘制一个小部件(名为“小部件”)。在my.ui文件中有一个小部件和一个图形视图。我正在尝试在小部件上实现绘画 paintEventTest.py文件如下所示:Python PySide2在设计器创建的小部件上绘制,python,python-3.x,qt-designer,pyside2,paintevent,Python,Python 3.x,Qt Designer,Pyside2,Paintevent,此问题与Win10和Python 3.6.6上的VS代码有关。我对Python和PySide2都是新手 我在StackOverflow上读了很多关于这个的主题,可能这是另一个主题的重复,但我无法绘制我的小部件 我知道widget对象的paintEvent()必须以某种方式重写。大多数示例都在主窗口上进行了一些绘制,但我无法将其从ui.file传输到widget上 我在.py文件中创建了两个类:MainForm和Drawer。MainForm包含UI的实现,我正在尝试绘制一个小部件(名为“小部件”
import sys
from PySide2 import QtWidgets
from PySide2 import QtGui
from PySide2 import QtCore
from PySide2.QtUiTools import QUiLoader
from PySide2.QtWidgets import (
QApplication, QPushButton, QLineEdit, QTextEdit, QSpinBox, QMainWindow, QDesktopWidget, QTableWidget,
QTableWidgetItem, QToolButton, QToolTip)
from PySide2.QtCore import QFile, QObject, Qt
class MainForm(QMainWindow):
def __init__(self, ui_file, parent=None):
super(MainForm, self).__init__(parent)
ui_file = QFile(ui_file)
ui_file.open(QFile.ReadOnly)
### Load UI file from Designer ###
loader = QUiLoader()
self.ui_window = loader.load(ui_file)
ui_file.close()
self.ui_window.show()
### THIS IS NOT WORKING (OBVIOUSLY?) ###
widget = self.ui_window.widget
drawer = Drawer()
drawer.paintEvent(widget)
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 = QtGui.QPainter(self)
qp.setPen(QtGui.QPen(Qt.green, 8, Qt.DashLine))
qp.drawEllipse(40, 40, 400, 400)
if __name__ == '__main__':
app = QApplication(sys.argv)
app.setStyle('Fusion')
form = MainForm('./UI designer/testUI.ui')
sys.exit(app.exec_())
testUI.ui看起来像这样,它在“ui设计器”文件夹中实现:
我还对使用graphicscene和graphicsitem在graphicsview上绘制等效代码感兴趣。正如您所指出的,应该只覆盖paintEvent。因此,一个选项是推广小部件,您可以在以下答案中看到几个示例:
├── main.py
├── mywidget.py
└── UI designer
└── testUI.ui
在mywidget.py文件中,实现所需的类:
mywidget.py
从PySide2导入QtCore、QtGui、QtWidgets
类抽屉(qtwidts.QWidget):
def喷漆事件(自身,e):
"""
将自动调用paintEvent()方法
QPainter类执行所有低级绘图
在其方法begin()和end()之间编码
"""
qp=QtGui.QPainter()
qp.开始(自我)
自绘制几何(qp)
qp.end()
def drawGeometry(自我,qp):
setPen(QtGui.QPen(QtCore.Qt.green,8,QtCore.Qt.DashLine))
qp.抽屉(40、40、400、400)
然后你必须用Qt设计器打开你的.ui,右键点击小部件并选择升级到。。。在上下文菜单中,然后用以下内容填充对话框:
按add按钮,然后按promote按钮生成以下.ui文件
主窗口
0
0
731
633
主窗口
0
200
0
250
16777215
300
0
0
731
23
抽屉
QWidget
mywidget
1.
另一方面,QUiLoader只加载Qt默认提供的小部件,因此如果要使用新的小部件,必须覆盖createWidget方法:
main.py
导入操作系统
导入系统
从PySide2导入QtCore、QtGui、QtWidgets、QtUiTools
从mywidget导入抽屉
类UiLoader(QtUiTools.QUiLoader):
def createWidget(self,className,parent=None,name=”“):
如果className==“抽屉”:
小部件=抽屉(父)
widget.setObjectName(名称)
返回小部件
return super(UiLoader,self).createWidget(className,parent,name)
类主窗体(QtCore.QObject):
def uuu init uuu(self,ui_文件,父项=无):
超级(MainForm,self)。\uuuu init\uuuuu(父级)
ui\u文件=QtCore.QFile(ui\u文件)
ui_file.open(QtCore.QFile.ReadOnly)
###从设计器加载UI文件###
loader=UiLoader()
self.ui\u window=loader.load(ui\u文件)
ui_file.close()
self.ui_window.show()
如果名称=“\uuuuu main\uuuuuuuu”:
app=qtwidts.QApplication(sys.argv)
应用程序设置样式(“融合”)
file=os.path.join(
os.path.dirname(os.path.realpath(_文件__)),“/UI designer/testUI.UI”
)
form=MainForm(文件)
sys.exit(app.exec_())
非常感谢,这很有效。这是正常的方法还是有其他方法?你有一些关于使用图形视图的想法吗?当我们创建新的小部件时,是否也可以实现样式表?我敢打赌答案是肯定的,但怎么做?@Grohl 1)正常是相对的,有一些限制(即使用.ui而不将其转换为.py),这是我认为唯一可以做到的方法。2) 我不明白你的问题。3) 您是否尝试设置样式表?如果是,你遇到了什么问题?最后,我将只回答您在前面的评论中指出的问题,如果您有其他问题,请创建另一篇文章,这些评论将讨论与您的出版物相关的问题。:-)(1)好的。2.)我确实在帖子底部提到了graphicsview问题,但我可以稍后再提出另一个问题。3.)我尝试在MainForm类、UiLoader类和Designer中设置样式表。我将使用代码样式表代码编辑原始帖子。@Grohl 2)您必须使用相同的代码,我的解决方案适用于任何小部件,对于其他小部件,请检查我在回答中提供的链接3)不要编辑问题,您的问题已经得到回答,如果您有其他问题,请创建其他帖子
QWidget::paintEngine: Should no longer be called
QPainter::begin: Paint device returned engine == 0, type: 1
QWidget::paintEngine: Should no longer be called
QPainter::begin: Paint device returned engine == 0, type: 1
QPainter::setPen: Painter not active
QPainter::end: Painter not active, aborted
├── main.py
├── mywidget.py
└── UI designer
└── testUI.ui