获取 Qt 小部件以更新使用 Qt Designer 制作的 Qt 表单中的鼠标事件

Posted

技术标签:

【中文标题】获取 Qt 小部件以更新使用 Qt Designer 制作的 Qt 表单中的鼠标事件【英文标题】:Getting a Qt Widget to update a mouse event inside a Qt form made with Qt Designer 【发布时间】:2019-02-16 14:26:43 【问题描述】:

我制作了一个自定义 QGraphicsView,我将其作为小部件添加到我使用 Qt Designer 制作的应用程序表单中。一切似乎都在工作,包括鼠标点击。进行绘图的方法被调用,但我无法在屏幕上实际重绘。我尝试创建paintEvent 方法的副本并调用mouseEvent 方法。我也尝试直接调用paintEvent。我似乎无法用 mouseEvent 重新绘制它。代码如下:

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
from PySide2.QtGui import QMouseEvent, QCursor, QPaintEvent
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, 450, 450)
        #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 mousePaintEvent(self):
        qp = QPainter()
        qp.begin(self.viewport())
        self.drawRectangles(qp)
        qp.end()

    def drawRectangles(self, qp, w = 20):
        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.paintEvent(QPaintEvent)
        #self.mousePaintEvent()
        self.update()
        self.repaint()      

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

【问题讨论】:

【参考方案1】:

你不应该直接调用paintEvent方法,创建一个类似名称的方法不会被神奇地调用。您必须调用viewport()update() 方法。

def mousePressEvent(self, event):
    w = 16.0
    x = int(event.x()*1.0/w)
    y = int(event.y()*1.0/w)
    s1, s2 = self.grid.shape
    # verify
    if 0 <= y < s1 and 0 <= x < s2:
        self.grid[x][y] = -self.grid[x][y]
        self.viewport().update()  

【讨论】:

我尝试创建一个方法,然后尝试从 mouseEvent 调用它,我没想到它会被神奇地调用;) viewport().update() 调用修复了一切!感谢您的帮助!

以上是关于获取 Qt 小部件以更新使用 Qt Designer 制作的 Qt 表单中的鼠标事件的主要内容,如果未能解决你的问题,请参考以下文章

Qt - 在 translate() 之后获取小部件内矩形的位置

如何在另一个小部件更新qt中的相同内容后更新小部件内容

从另一个线程更新 QT 小部件的不那么冗长的方法?

Qt:如何获取特定小部件的像素指标

如何使用 Qt/C++ 小部件(不是 QML)从 Android 相机获取图像

获取相对于 Qt OpenGL 小部件的鼠标坐标