Python 获取一个自定义QtQGraphicsView,以QtDesigner制作的表单显示

Python 获取一个自定义QtQGraphicsView,以QtDesigner制作的表单显示,python,qt,pyqt,qt-designer,qgraphicsview,Python,Qt,Pyqt,Qt Designer,Qgraphicsview,我创建了一个定制的QGraphicsView,可以在Python的主窗口中显示,但我很难将它集成到我用Qt Designer制作的表单中。如何将其添加到表单中 此外,我还添加了鼠标按下事件。如何使用Qt Designer制作的表单将其集成到应用程序中?我已经使用Qt Designer构建了一个完整的应用程序,其他一切都可以使用,我只需要能够将这一部分与其余部分一起添加 import sys from PySide2 import QtCore, QtGui, QtWidgets from PyQ

我创建了一个定制的QGraphicsView,可以在Python的主窗口中显示,但我很难将它集成到我用Qt Designer制作的表单中。如何将其添加到表单中

此外,我还添加了鼠标按下事件。如何使用Qt Designer制作的表单将其集成到应用程序中?我已经使用Qt Designer构建了一个完整的应用程序,其他一切都可以使用,我只需要能够将这一部分与其余部分一起添加

import sys
from PySide2 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QFileDialog
from PySide2.QtUiTools import QUiLoader
from PySide2.QtWidgets import QApplication, QPushButton, QLineEdit, QAction, QSlider
from PySide2.QtWidgets import QListWidget, QTabWidget, QGraphicsView, QGraphicsScene
from PySide2.QtWidgets import QSpinBox, QWidget, QDialog, QVBoxLayout
from PySide2.QtGui import QPixmap, QImage, QMatrix, QPainter, QColor, QMouseEvent, QCursor
from PySide2.QtCore import QFile, QObject, SIGNAL

import cv2
import numpy as np
import math

class Display_Pixels(QGraphicsView):

    def __init__(self, parent=None):
        QGraphicsView.__init__(self, parent=parent)
        #super().__init__()
        self.initUI()
        self.img = cv2.imread('roi.jpg')

    def initUI(self):      
        self.setGeometry(100, 100, 650, 650)
        #self.setWindowTitle('By Pixel')
        #self.setMouseTracking(True)
        #self.show()
        res = 40 
        self.grid = np.array([ [-1] * res  for n in range(res)]) # list comprehension
        #print(self.grid.shape)


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


    def drawRectangles(self, qp, w = 16):
        print("Drawing")
        mode = 0
        x,y = 0,0 # starting position
        lr = 20
        hr = 35
        col = QColor(0, 0, 0)
        col.setNamedColor('#d4d4d4')
        qp.setPen(col)
        #print(self.img.shape)

        for g_row, img_row in zip(self.grid, self.img):
            #print(img_row.shape)
            for g_col, img_col in zip(g_row, img_row):
                r, g, b = (img_col[0], img_col[1], img_col[2])
                #print(r,g,b)

                if g_col == 1:
                    if mode == 0:
                        r = int(math.log(r+1)*lr)
                        g = int(math.log(g+1)*hr)
                        b = int(math.log(b+1)*lr)
                    elif mode == 1:
                        if r+50 <= 220: r = r+50
                        if g+80 <= 255: g = g+80
                        if b+50 <= 220: b = b+50
                    else:
                        if r+70 <= 220: r = r+70
                        if g+140 <= 255: g = g+140
                        if b+70 <= 220: b = b+70

                    qp.setBrush(QColor(r, g, b))
                    qp.drawRect(x, y, w, w)
                else:
                    qp.setBrush(QColor(r, g, b))
                    qp.drawRect(x, y, w, w)

                #qp.setBrush(QColor(200, 0, 0))
                #qp.drawRect(x, y, w, w)
                x = x + w  # move right
            y = y + w # move down
            x = 0 # rest to left edge


    def mousePressEvent(self, QMouseEvent):
        w = 16.0

        #print("MOUSE:")
        #print('(', int(QMouseEvent.x()/w), ', ', int(QMouseEvent.y()/w), ')')
        #print (QMouseEvent.pos())
        x = float(QMouseEvent.x())
        y = float(QMouseEvent.y())
        self.grid[int(y/w)][int(x/w)] = -1 * self.grid[int(y/w)][int(x/w)]

        #print(img[int(y/w), int(x/w), :])

        self.repaint()
        #self.update()


if __name__ == '__main__':
    app = QApplication.instance()
    if app is None: 
        app = QApplication(sys.argv)
    px = Display_Pixels()
    px.show()
    sys.exit(app.exec_())

我认为您的意思是您成功地将此代码添加到主窗口,但您希望能够将其添加到在designer中制作的小部件中,而不是严格意义上的主窗口

如果是这种情况,您需要做的是按照您希望的方式在Qt Designer中设置小部件的格式,添加一个占位符,例如一个框架、布局,可能是一个组,在其中插入显示像素QGraphicsView对象

之后,不会直接将其添加到框架中,而是使用框架使用的任何布局。因此,如果您的框架中有一个gridlayout,它将类似于:

    self.Disp_pixel = Display_Pixels()
    widget_name.gridlayout.addWidget(self.Disp_pixel)
很难告诉您该代码将在代码中的何处实现,但假设您运行了pyuic5并获得了python输出。您可以将其添加到输出python文件中。我建议使用类似于查看器类的东西来继承生成的输出类,并在其中添加小部件。另外,frame是为图形视图创建的框架的名称,而不是字面上的框架

此外,我不确定你是否可以在任何类型的小部件上进行显示,我非常确定小部件必须是可显示的,例如主窗口小部件或对话框小部件。也就是说,widget可以放在其他widget中

下面是一个我给你的例子,它有点粗糙,但我认为它会有帮助:

import sys
import cv2
import numpy as np
import math

from PyQt5.QtGui import QPainter, QColor
from PyQt5.QtWidgets import QGraphicsView, QApplication

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file '.\testUI.ui' and .\testMainWin.ui
#
# Created by: PyQt5 UI code generator 5.9.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(800, 600)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.gridLayout = QtWidgets.QGridLayout(self.centralwidget)
        self.gridLayout.setObjectName("gridLayout")
        MainWindow.setCentralWidget(self.centralwidget)

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

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))

class Ui_Form(object):
    def setupUi(self, Form):
        Form.setObjectName("Form")
        Form.resize(400, 300)
        self.gridLayout = QtWidgets.QGridLayout(Form)
        self.gridLayout.setObjectName("gridLayout")
        self.frame = QtWidgets.QFrame(Form)
        self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
        self.frame.setFrameShadow(QtWidgets.QFrame.Raised)
        self.frame.setObjectName("frame")
        self.gridLayout_2 = QtWidgets.QGridLayout(self.frame)
        self.gridLayout_2.setObjectName("gridLayout_2")
        self.gridLayout.addWidget(self.frame, 0, 0, 1, 1)

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

    def retranslateUi(self, Form):
        _translate = QtCore.QCoreApplication.translate
        Form.setWindowTitle(_translate("Form", "Form"))


class FormView(QtWidgets.QWidget, Ui_Form):
    def __init__(self, parent=None):
        super(FormView, self).__init__(parent)
        self.setupUi(self)
        self.disp_pixels = Display_Pixels()
        self.gridLayout_2.addWidget(self.disp_pixels)


class MainView(QtWidgets.QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        super(MainView, self).__init__(parent)
        self.setupUi(self)


class Display_Pixels(QGraphicsView):

    def __init__(self, parent=None):
        QGraphicsView.__init__(self, parent=parent)
        #super().__init__()
        self.initUI()
        self.img = cv2.imread('resources/images/pic3.jpg')

    def initUI(self):
        self.setGeometry(100, 100, 650, 650)
        #self.setWindowTitle('By Pixel')
        #self.setMouseTracking(True)
        #self.show()
        res = 40
        self.grid = np.array([ [-1] * res  for n in range(res)]) # list comprehension
        #print(self.grid.shape)

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


    def drawRectangles(self, qp, w = 16):
        print("Drawing")
        mode = 0
        x,y = 0,0 # starting position
        lr = 20
        hr = 35
        col = QColor(0, 0, 0)
        col.setNamedColor('#d4d4d4')
        qp.setPen(col)
        #print(self.img.shape)

        for g_row, img_row in zip(self.grid, self.img):
            #print(img_row.shape)
            for g_col, img_col in zip(g_row, img_row):
                r, g, b = (img_col[0], img_col[1], img_col[2])
                #print(r,g,b)

                if g_col == 1:
                    if mode == 0:
                        r = int(math.log(r+1)*lr)
                        g = int(math.log(g+1)*hr)
                        b = int(math.log(b+1)*lr)
                    elif mode == 1:
                        if r+50 <= 220: r = r+50
                        if g+80 <= 255: g = g+80
                        if b+50 <= 220: b = b+50
                    else:
                        if r+70 <= 220: r = r+70
                        if g+140 <= 255: g = g+140
                        if b+70 <= 220: b = b+70

                    qp.setBrush(QColor(r, g, b))
                    qp.drawRect(x, y, w, w)
                else:
                    qp.setBrush(QColor(r, g, b))
                    qp.drawRect(x, y, w, w)

                #qp.setBrush(QColor(200, 0, 0))
                #qp.drawRect(x, y, w, w)
                x = x + w  # move right
            y = y + w # move down
            x = 0 # rest to left edge


    def mousePressEvent(self, QMouseEvent):
        w = 16.0

        #print("MOUSE:")
        #print('(', int(QMouseEvent.x()/w), ', ', int(QMouseEvent.y()/w), ')')
        #print (QMouseEvent.pos())
        x = float(QMouseEvent.x())
        y = float(QMouseEvent.y())
        self.grid[int(y/w)][int(x/w)] = -1 * self.grid[int(y/w)][int(x/w)]

        #print(img[int(y/w), int(x/w), :])

        self.repaint()
        #self.update()


if __name__ == '__main__':
    app = QApplication.instance()
    if app is None:
        app = QApplication(sys.argv)
    main_window = MainView()
    form = FormView()
    main_window.gridLayout.addWidget(form)
    main_window.show()

    sys.exit(app.exec_())

我添加了以下几行代码,似乎可以做到这一点:self.edit\u layout=self.window.findChildQHBoxLayout,“Editor\u layout”self.view=Display\u Pixels self.view.installEventFilterself.edit\u layout.addWidgetself.view.view.show这是不相关的,但我的编码技能显然不是最好的。我仍然不明白为什么主窗口和窗体最好有单独的类。还有,儿童班有什么意义?这完全取决于你。我喜欢这样把事情分开。我正在使用一种接近模型、视图和控制器的设计模式,所以它适合我。不过你不必那样做。代码基本相同,除了FormView中的两行代码,我在其中初始化显示像素,然后将其添加到gridlayout,这将被移动到Ui表单类。此外,Ui_表单是从我创建的Ui文件生成的,然后使用pyuic5转换为python,所以您很可能希望自己创建。这取决于你。啊,MVC,我忘了这个!我已经很久没有在大学上过编码课了。非常感谢你的帮助!