Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/362.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python PySide2在设计器创建的小部件上绘制_Python_Python 3.x_Qt Designer_Pyside2_Paintevent - Fatal编程技术网

Python PySide2在设计器创建的小部件上绘制

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的实现,我正在尝试绘制一个小部件(名为“小部件”

此问题与Win10和Python 3.6.6上的VS代码有关。我对Python和PySide2都是新手

我在StackOverflow上读了很多关于这个的主题,可能这是另一个主题的重复,但我无法绘制我的小部件

我知道widget对象的paintEvent()必须以某种方式重写。大多数示例都在主窗口上进行了一些绘制,但我无法将其从ui.file传输到widget上

我在.py文件中创建了两个类:MainForm和Drawer。MainForm包含UI的实现,我正在尝试绘制一个小部件(名为“小部件”)。在my.ui文件中有一个小部件和一个图形视图。我正在尝试在小部件上实现绘画

paintEventTest.py文件如下所示:

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