python - 获取自定义 Qt QGraphicsView 以显示在使用 Qt Designer 制作的表单中

标签 python qt pyqt qt-designer qgraphicsview

我组装了一个自定义的 QGraphicsView,可以在 Python 的主窗口中显示它,但我正在努力将其集成到我用 Qt Designer 制作的表单中。我如何将其添加到表单中?

此外,我还添加了 mousepress 事件。如何使用 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_())

最佳答案

我认为你的意思是你成功地将这段代码添加到主窗口中,但你希望能够将其添加到你在设计器中制作的小部件中,而不是严格的主窗口中。

如果是这种情况,您需要做的就是在 Qt Designer 中按照您想要的方式格式化您的小部件,添加一个占位符,例如框架、布局,也许是一个组等,您想要在其中插入 Display_Pixels QGraphicsView 对象。

之后不会直接将其添加到框架中,而是框架正在使用的任何布局。所以如果你的框架中有一个网格布局,它会是这样的:

    self.Disp_pixel = Display_Pixels()
    widget_name.gridlayout.addWidget(self.Disp_pixel)

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

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

这是我为您提供的一个示例,它有点粗糙,但我认为它会有所帮助:

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_())

关于python - 获取自定义 Qt QGraphicsView 以显示在使用 Qt Designer 制作的表单中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54708398/

相关文章:

python - 在 NixOS 中,如何解决冲突?

python - 使用 PyQt 和 Socket 进行聊天编程 [标准库]

pyqt - 如何创建一个 3 色渐变表盘指示器(显示绿-黄-红的那个)

python - 在 PyQt5 中连接多个数据库

python - 从每个键具有多个唯一值的字符串列表创建一个 3 级字典

python - 想要替换 python3 字符串中的反斜杠

python - 无法在python中使用selenium打开IE

C++ Qt QtConcurrent::filteredReduced 从 std::shared_ptr 的 QVector

c++ - 使用 QT_SCALE_FACTOR 缩放时,如何防止 QGraphicsScene 中的 QListView 在滚动区域外绘制

qt - 无法通过 SplitView 中的 id 访问 QML 项目