Как сделать чтобы при нажатии кнопки рисовалось в graphicsview или появлялось новое окно с рисунком?

Желательно чтобы рисовалось в graphicsview и в новом окне одновременно.

При нажатии на кнопку всё закрывается без вывода ошибки.

Предоставляю код:

from PyQt5 import QtCore, QtGui, QtWidgets
import sys


class Ui_Dialog(object):
    def setupUi(self, Dialog):
        Dialog.setObjectName("Dialog")
        Dialog.resize(654, 626)
        self.graphicsView = QtWidgets.QGraphicsView(Dialog)
        self.graphicsView.setGeometry(QtCore.QRect(0, 330, 651, 291))
        self.graphicsView.setObjectName("graphicsView")
        self.pushButton = QtWidgets.QPushButton(Dialog)
        self.pushButton.setGeometry(QtCore.QRect(190, 120, 75, 23))
        self.pushButton.setObjectName("pushButton")
        self.lineEdit = QtWidgets.QLineEdit(Dialog)
        self.lineEdit.setGeometry(QtCore.QRect(410, 60, 113, 20))
        self.lineEdit.setObjectName("lineEdit")

        self.retranslateUi(Dialog)
        QtCore.QMetaObject.connectSlotsByName(Dialog)

        self.pushButton.clicked.connect(self.test)

    def retranslateUi(self, Dialog):
        _translate = QtCore.QCoreApplication.translate
        Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
        self.pushButton.setText(_translate("Dialog", "PushButton"))

    def test(self):
        a = 50
        d = 8
        l = round(a + 1.5 * d)
        ms = 6

        if l < 16 or l > 160:
            print('error')
        else:

            class Example(QWidget):
                def __init__(self):
                    super().__init__()
                    self.initUI()

                def initUI(self):
                    self.setGeometry(500, 300, 700, 600)
                    self.show()

                def paintEvent(self, e):
                    qp = QPainter()
                    qp.begin(self)

                    self.drawBrushes(qp)
                    self.vint(qp)
                    self.drawLines(qp)

                    qp.end()

                def vint(self, qp):
                    brush = QBrush(QColor('white'))
                    qp.setBrush(brush)

                    qp.drawRect(210, 115, l * ms, d * ms)  

                def drawBrushes(self, qp):
                    pen = QPen(Qt.black, 2, Qt.SolidLine)
                    qp.setPen(pen)
                    qp.setBrush(QColor('white'))

                    qp.drawRect(210, 35, a * ms, 200)  
                    qp.drawRect(210 + a * ms, 35, 35 * 5, 200)

                    brush = QBrush(Qt.BDiagPattern)
                    qp.setBrush(brush)
                    qp.drawRect(210, 35, a * ms, 200)  # левый фланец

                    brush.setStyle(Qt.FDiagPattern)
                    qp.setBrush(brush)
                    qp.drawRect(210 + a * ms, 35, 35 * 5, 200)  

                def drawLines(self, qp):
                    pen = QPen(Qt.black, 1, Qt.DashDotLine)
                    qp.setPen(pen)
                    qp.drawLine(180, 140, 210 * 2 + a * ms, 140)

            if __name__ == '__main__':
                app = QApplication(sys.argv)
                ex = Example()
                sys.exit(app.exec_())


if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    Dialog = QtWidgets.QDialog()
    ui = Ui_Dialog()
    ui.setupUi(Dialog)
    Dialog.show()
    sys.exit(app.exec_())

Ответы (1 шт):

Автор решения: S. Nick

НИКОГДА НЕ ИЗМЕНЯЙТЕ код, сгенерированный Qt Designer, НИКОГДА.
Создайте другой класс, который наследуется от соответствующего виджета, и используйте созданный класс для его заполнения.

Вы должны получить ошибку:

QCoreApplication::exec: The event loop is already running

потому что строка:

app = QApplication(sys.argv)

в приложении может быть только одна.

import sys
import math
import random
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.Qt import *


class Ui_Dialog(object):
    def setupUi(self, Dialog):
        Dialog.setObjectName("Dialog")
        Dialog.resize(654, 626)
        
        self.graphicsView = QtWidgets.QGraphicsView(Dialog)
        self.graphicsView.setGeometry(QtCore.QRect(0, 330, 651, 291))
        self.graphicsView.setObjectName("graphicsView")
        
        self.pushButton = QtWidgets.QPushButton(Dialog)
        self.pushButton.setGeometry(QtCore.QRect(190, 120, 75, 23))
        self.pushButton.setObjectName("pushButton")
        
        self.lineEdit = QtWidgets.QLineEdit(Dialog)
        self.lineEdit.setGeometry(QtCore.QRect(410, 60, 113, 20))
        self.lineEdit.setObjectName("lineEdit")

        self.retranslateUi(Dialog)
        QtCore.QMetaObject.connectSlotsByName(Dialog)

    def retranslateUi(self, Dialog):
        _translate = QtCore.QCoreApplication.translate
        Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
        self.pushButton.setText(_translate("Dialog", "PushButton"))


class QRegularPolygon(QGraphicsPolygonItem):
    def __init__(self, sides, radius, center, angle=None, parent=None):
        super(QRegularPolygon,self).__init__(parent)
        self.setFlag(QGraphicsItem.ItemIsMovable, True)

        self._sides = sides
        self._radius = radius
        if angle != None: 
            self._angle = angle
        else: 
            self._angle = 0.0
        self._center = center

        points = list()
        for s in range(self._sides):
            angle = self._angle + (2 * math.pi * s / self._sides)
            x = center.x() + (radius * math.cos(angle))
            y = center.y() + (radius * math.sin(angle))
            points.append(QPointF(x, y))

        self.setPolygon(QPolygonF(points))

        self.tx, self.ty = 200, 200       
        
    def doRotate(self, alfa):
        tr = QTransform()
        tr.translate(self.tx, self.ty)
        tr.rotate(alfa)
        tr.translate(-self.tx, -self.ty)
        self.r, self.g, self.b = random.randint(0, 255), \
                                 random.randint(0, 255), \
                                 random.randint(0, 255)
        self.setBrush(QColor(self.r, self.g, self.b))
        self.setTransform(tr)
        

class Example(QWidget):
    def __init__(self, a, d, l, ms):
        super().__init__()
        self.resize(900, 300)
        
        self.a, self.d, self.l, self.ms = a, d, l, ms

    def paintEvent(self, e):
        qp = QPainter()
        qp.begin(self)

        self.drawBrushes(qp)
        self.vint(qp)
        self.drawLines(qp)

        qp.end()

    def vint(self, qp):
        brush = QBrush(QColor('white'))
        qp.setBrush(brush)

        qp.drawRect(210, 115, self.l * self.ms, self.d * self.ms)  

    def drawBrushes(self, qp):
        pen = QPen(Qt.black, 2, Qt.SolidLine)
        qp.setPen(pen)
        qp.setBrush(QColor('white'))

        qp.drawRect(210, 35, self.a * self.ms, 200)  
        qp.drawRect(210 + self.a * self.ms, 35, 35 * 5, 200)

        brush = QBrush(Qt.BDiagPattern)
        qp.setBrush(brush)
        qp.drawRect(210, 35, self.a * self.ms, 200)  # левый фланец

        brush.setStyle(Qt.FDiagPattern)
        qp.setBrush(brush)
        qp.drawRect(210 + self.a * self.ms, 35, 35 * 5, 200)  

    def drawLines(self, qp):
        pen = QPen(Qt.black, 1, Qt.DashDotLine)
        qp.setPen(pen)
        qp.drawLine(180, 140, 210 * 2 + self.a * self.ms, 140)
                    
                
class Dialog(QtWidgets.QDialog, Ui_Dialog):
    def __init__(self):
        super().__init__()  
        self.setupUi(self)

        self.pushButton.clicked.connect(self.test)

        self.scene = QGraphicsScene()
        self.graphicsView.setScene(self.scene)
        

    def test(self):
        a = 50
        d = 8
        l = round(a + 1.5 * d)
        ms = 6

        if l < 16 or l > 160:
            print('error')
        else:
            self.ex = Example(a, d, l, ms)
            self.ex.show()

            self.draw_scene()

    def draw_scene(self):
            self.square = QGraphicsRectItem(0, 0, 400, 400)
            self.square.setPen(QPen(Qt.GlobalColor.cyan, 5, Qt.SolidLine))
            self.square.setBrush(QBrush((Qt.gray)))
            self.scene.addItem(self.square)

            radius = 100                          # радиус описанной окружности
            ri = int(radius / 2 * math.sqrt(3))   # радиус вписанной окружности
            sides = 6                             # сторон у hexagon
            angle = math.pi / 2
            xcenter = 200
            ycenter = 200
            center = QPointF(xcenter, ycenter)

            self.hexagon = QRegularPolygon(sides, ri, center, angle)
            self.hexagon.setPen(QPen(Qt.GlobalColor.red, 5, Qt.SolidLine))
            self.hexagon.setBrush(QBrush((Qt.darkBlue)))
            self.scene.addItem(self.hexagon)
        

if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    w = Dialog()
    w.show()
    sys.exit(app.exec_())

введите сюда описание изображения

→ Ссылка