【问题标题】:How can I draw inside existing QGraphicsVIew?如何在现有的 QGraphicsVIew 中绘图?
【发布时间】:2017-10-26 20:31:06
【问题描述】:

正如标题所说,我正在尝试在现有的 QGraphicsView 中绘图。我使用 QT Designer 生成的窗口,我想在 QGraphicsView 内绘制一个 16x16 正方形的矩阵。

这是我现在拥有的代码:

窗口:

# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'untitled.ui'
#
# Created by: PyQt5 UI code generator 5.8.2
#
# WARNING! All changes made in this file will be lost!

from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(911, 567)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.label = QtWidgets.QLabel(self.centralwidget)
        self.label.setGeometry(QtCore.QRect(20, 10, 301, 31))
        font = QtGui.QFont()
        font.setPointSize(12)
        font.setBold(True)
        font.setWeight(75)
        self.label.setFont(font)
        self.label.setObjectName("label")
        self.groupBox = QtWidgets.QGroupBox(self.centralwidget)
        self.groupBox.setGeometry(QtCore.QRect(620, 40, 271, 91))
        font = QtGui.QFont()
        font.setBold(True)
        font.setWeight(75)
        self.groupBox.setFont(font)
        self.groupBox.setObjectName("groupBox")
        self.rdtest = QtWidgets.QRadioButton(self.groupBox)
        self.rdtest.setGeometry(QtCore.QRect(60, 60, 101, 22))
        self.rdtest.setObjectName("rdtest")
        self.rdtrain = QtWidgets.QRadioButton(self.groupBox)
        self.rdtrain.setGeometry(QtCore.QRect(60, 30, 101, 22))
        self.rdtrain.setObjectName("rdtrain")
        self.graphicsView = QtWidgets.QGraphicsView(self.centralwidget)
        self.graphicsView.setGeometry(QtCore.QRect(10, 40, 601, 411))
        self.graphicsView.setObjectName("graphicsView")
        self.clear = QtWidgets.QPushButton(self.centralwidget)
        self.clear.setGeometry(QtCore.QRect(10, 470, 88, 29))
        self.clear.setObjectName("clear")
        self.trainNewInput = QtWidgets.QPushButton(self.centralwidget)
        self.trainNewInput.setGeometry(QtCore.QRect(500, 470, 111, 29))
        self.trainNewInput.setObjectName("trainNewInput")
        self.trainbox = QtWidgets.QGroupBox(self.centralwidget)
        self.trainbox.setGeometry(QtCore.QRect(620, 150, 271, 171))
        font = QtGui.QFont()
        font.setBold(True)
        font.setWeight(75)
        self.trainbox.setFont(font)
        self.trainbox.setObjectName("trainbox")
        self.vtrain = QtWidgets.QLineEdit(self.trainbox)
        self.vtrain.setGeometry(QtCore.QRect(100, 70, 101, 29))
        self.vtrain.setObjectName("vtrain")
        self.label_2 = QtWidgets.QLabel(self.trainbox)
        self.label_2.setGeometry(QtCore.QRect(40, 70, 56, 31))
        font = QtGui.QFont()
        font.setBold(True)
        font.setWeight(75)
        self.label_2.setFont(font)
        self.label_2.setObjectName("label_2")
        self.trainDefault = QtWidgets.QPushButton(self.trainbox)
        self.trainDefault.setGeometry(QtCore.QRect(40, 30, 161, 29))
        self.trainDefault.setObjectName("trainDefault")
        self.output = QtWidgets.QLabel(self.trainbox)
        self.output.setGeometry(QtCore.QRect(10, 130, 271, 17))
        self.output.setText("")
        self.output.setObjectName("output")
        self.output_2 = QtWidgets.QLabel(self.trainbox)
        self.output_2.setGeometry(QtCore.QRect(10, 150, 271, 17))
        self.output_2.setText("")
        self.output_2.setObjectName("output_2")
        self.testbox = QtWidgets.QGroupBox(self.centralwidget)
        self.testbox.setGeometry(QtCore.QRect(620, 330, 271, 171))
        font = QtGui.QFont()
        font.setBold(True)
        font.setWeight(75)
        self.testbox.setFont(font)
        self.testbox.setObjectName("testbox")
        self.pushButton = QtWidgets.QPushButton(self.testbox)
        self.pushButton.setGeometry(QtCore.QRect(50, 40, 161, 29))
        self.pushButton.setObjectName("pushButton")
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 911, 23))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

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

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.label.setText(_translate("MainWindow", "RNA: Numeros "))
        self.groupBox.setTitle(_translate("MainWindow", "Opciones:"))
        self.rdtest.setText(_translate("MainWindow", "Test"))
        self.rdtrain.setText(_translate("MainWindow", "Train"))
        self.clear.setText(_translate("MainWindow", "Clear"))
        self.trainNewInput.setText(_translate("MainWindow", "Train new Input"))
        self.trainbox.setTitle(_translate("MainWindow", "Train:"))
        self.label_2.setText(_translate("MainWindow", "% Test:"))
        self.trainDefault.setText(_translate("MainWindow", "Train Default Data"))
        self.testbox.setTitle(_translate("MainWindow", "Test:"))
        self.pushButton.setText(_translate("MainWindow", "Start Test"))


if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

我想在其中创建一个从窗口中绘制 QGraphicsView 的方法的逻辑类:

import sys
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QGraphicsScene
from PyQt5.QtCore import (QLineF, QPointF, QRectF, Qt)
from PyQt5.QtWidgets import QWidget, QApplication
from PyQt5.QtWidgets import (QApplication, QGraphicsView, QGraphicsScene, QGraphicsItem,
                             QGridLayout, QVBoxLayout, QHBoxLayout,
                             QLabel, QLineEdit, QPushButton)
from window import Ui_MainWindow
from RNA import NumberIA

train = []
train_r = []
test = []
test_r = []


class MyFirstGuiProgram(Ui_MainWindow):
    def __init__(self, dialog):
        Ui_MainWindow.__init__(self)

        self.setupUi(dialog)
        self.rdtrain.setChecked(True)

        # Connect "add" button with a custom function (addInputTextToListbox)
        self.clear.clicked.connect(self.addInputTextToListbox)
        self.trainDefault.clicked.connect(self.t_DefaultData)
        self.rdtest.clicked.connect(self.enableTest)
        self.rdtrain.clicked.connect(self.enableTrain)

    def enableTest(self):
        self.trainbox.setEnabled(False)
        self.trainNewInput.setEnabled(False)
        self.testbox.setEnabled(True)

    def drawSomething(self):
        tes = "f"

    def enableTrain(self):
        self.trainbox.setEnabled(True)
        self.trainNewInput.setEnabled(True)
        self.testbox.setEnabled(False)

    def addInputTextToListbox(self):
        print("Hello world!!!")

    def t_DefaultData(self):
        ann = NumberIA()

        t = self.vtrain.text()
        print("Training data: ", t)

        global train
        global train_r
        global test
        global test_r
        train, train_r, test, test_r = ann.read_file(float(t))
        self.output.setText("Train complete...")

        ann.crear_red(train, train_r)
        accuracy, matrix = ann.probar_red(test, test_r)
        self.output_2.setText("Accuracy: " + str(accuracy * 100) + "%")

        print("Matris de Confusion:")
        print('\n'.join([''.join(['{:4}'.format(item) for item in row])
                         for row in matrix]))


if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = MyFirstGuiProgram(MainWindow)
    MainWindow.show()
    MainWindow.setWindowTitle("RNA: Inteligencia Artificial 2")
    ui.enableTrain()
    sys.exit(app.exec_())

我似乎无法在网上找到如何做到这一点的例子,我发现的例子对我来说很模糊,似乎无法弄清楚。

【问题讨论】:

    标签: python pyqt pyqt5 qt-designer qgraphicsview


    【解决方案1】:

    我建议你从QMainWindow继承并实现Ui_MainWindow接口,要绘制QGraphicsView你必须使用QGraphicsScene,并使用它的方法,在这种情况下使用addRect()

    from PyQt5 import QtCore, QtGui, QtWidgets
    
    class MyFirstGuiProgram(QtWidgets.QMainWindow, Ui_MainWindow):
        def __init__(self, parent=None):
            QtWidgets.QMainWindow.__init__(self, parent=parent)
            self.setupUi(self)
            scene = QtWidgets.QGraphicsScene()
            self.graphicsView.setScene(scene)
            pen = QtGui.QPen(QtCore.Qt.green)
    
            side = 20
    
            for i in range(16):
                for j in range(16):
                    r = QtCore.QRectF(QtCore.QPointF(i*side, j*side), QtCore.QSizeF(side, side))
                    scene.addRect(r, pen)
    
    
    if __name__ == '__main__':
        import sys
        app = QtWidgets.QApplication(sys.argv)
        w = MyFirstGuiProgram()
        w.show()
        sys.exit(app.exec_())
    

    【讨论】:

      【解决方案2】:

      你也可以通过 QLineF() 来绘制它,它从设计的角度提供了更多的控制。

      import sys
      from PyQt5.QtCore import *
      from PyQt5.QtGui import *
      from PyQt5.QtWidgets import *
      
      def sceneWithPen(grid):
      
          scene = QGraphicsScene()
          view = QGraphicsView()
          view.setScene(scene)
                                              # Creating line's colors
          red = QColor(qRgb(172, 50, 99))
          blue = QColor(qRgb(50, 150, 203))
                                              # Set length of square's side and number of horizontal and vertical lines
          vLines = 16
          hLines = 16
          side = 30
                                              # Set starting values for loops
          hor = 0
          ver = 0
          subdiv = 16
          leftX,leftY = 0, 0
          rightX, rightY = subdiv*side, 0
          bottomX, bottomY= 0, 0
          topX, topY = 0, subdiv*side
      
          while ver < vLines:
                                              # Drawing vertical lines
              ver = ver + 1
              vLine = QLineF(bottomX, bottomY, topX, topY)
              bottomX, topX = bottomX + side, topX + side
              scene.addLine(vLine, red)
      
          while hor < hLines:
                                              #Drawing horizontal lines
              hor = hor + 1
              hLine = QLineF(leftX, leftY, rightX, rightY)
              leftY, rightY = leftY + side, rightY + side
              scene.addLine(hLine, blue)
      
          grid.addWidget(view)
      
      if __name__ == '__main__':
          app = QApplication(sys.argv)
          w = QWidget()
          grid = QGridLayout()
          sceneWithPen(grid)
          w.setLayout(grid)
          w.show()
          sys.exit(app.exec_())
      

      会是这样的:

      【讨论】:

        【解决方案3】:

        @eyllanesc 刚刚在上面给了你一个很好的例子,如果你需要像一个简单的徒手一样画画,这里是另一个我碰巧放在周围的小例子。

        1. 拥有您的 MainWindow,例如 QMainWindow 或 Qwidget 或...
        2. 有一个 QGraphicsView。
        3. 使用您的 QGraphicsScene 设置 QGraphicsView 的场景
        4. 拥有自己的 QGraphicsPathItem,以便设置所需的属性。
        5. 在场景中实现您想要绘制的内容,这样它就知道如何在自己上绘制。

        通过这种方式,您将可以控制多个场景,知道如何独立绘制自己,当然如果您需要多个场景。

        这个例子的逻辑是在 QGraphicsView 中实现的,你可以把它移到你的 GraphicsScene 中。

        class MainWindow(QMainWindow):
        
            central_widget = None
            layout_container = None
        
            def __init__(self):
                super(MainWindow, self).__init__()
                self.central_widget = QWidget()
                self.layout_container = QVBoxLayout()
                self.central_widget.setLayout(self.layout_container)
                self.setCentralWidget(self.central_widget)
                self.layout_container.addWidget(GraphicsView())
        
        class GraphicsView(QGraphicsView):
        
            start = None
            end = None
            item = None
            path = None
        
            def __init__(self):
                super(GraphicsView, self).__init__()
                self.setScene(QGraphicsScene())
                self.path = QPainterPath()
                self.item = GraphicsPathItem()
                self.scene().addItem(self.item)
        
            def mousePressEvent(self, event):
                self.start = self.mapToScene(event.pos())
                self.path.moveTo(self.start)
        
            def mouseMoveEvent(self, event):
                self.end = self.mapToScene(event.pos())
                self.path.lineTo(self.end)
                self.start = self.end
                self.item.setPath(self.path)
        
        class GraphicsPathItem(QGraphicsPathItem):
        
            def __init__(self):
                super(GraphicsPathItem, self).__init__()
                pen = QPen()
                pen.setColor(Qt.black)
                pen.setWidth(10)
                self.setPen(pen)
        
        if __name__ == '__main__':
            app = QApplication(sys.argv)
            mw = MainWindow()
            mw.show()
            sys.exit(app.exec_())
        

        【讨论】:

        • 很好的例子!正是我当前项目所需要的。感谢您创建它。
        猜你喜欢
        • 2018-09-16
        • 1970-01-01
        • 2011-11-11
        • 1970-01-01
        • 2017-04-12
        • 2017-11-26
        • 1970-01-01
        • 2021-01-16
        • 1970-01-01
        相关资源
        最近更新 更多