【问题标题】:PyQt5: Maintain previously drawn drawings/line when new ones are drawnPyQt5:绘制新的绘图/线条时保持先前绘制的绘图/线条
【发布时间】:2018-10-02 17:50:05
【问题描述】:

在绘制新线后,我无法维护先前绘制的线。现在,如果我单击一个按钮,它将绘制一条线,但是一旦我单击第二个按钮,就会绘制一条新线,并删除最初的一条线。我希望两者都保留。

import sys
from PyQt5.QtWidgets import QMainWindow,QPushButton, QApplication
from PyQt5.QtCore import QSize, Qt, QLine, QPoint
from PyQt5.QtGui import QPainter, QPen

class MainWindow(QMainWindow):
    def __init__(self):
        QMainWindow.__init__(self)

        self.setMinimumSize(QSize(300, 300)) 

        pybutton = QPushButton('button', self)
        pybutton.clicked.connect(self.draw_line)
        pybutton.resize(100,100)
        pybutton.move(0, 0) 

        pybutton2 = QPushButton('button2', self)
        pybutton2.clicked.connect(self.draw_line)
        pybutton2.resize(100,100)
        pybutton2.move(200, 0) 
        self.line = QLine()

    def draw_line(self):
        button = self.sender()
        x = int(button.x()) + int(button.width())/2
        y = int(button.y())+100
        self.line = QLine(x, y, x, y+100)
        self.update()

    def paintEvent(self,event):
        QMainWindow.paintEvent(self, event)
        if not self.line.isNull():
            painter = QPainter(self)
            pen = QPen(Qt.red, 3)
            painter.setPen(pen)
            painter.drawLine(self.line)

if __name__ == "__main__":
    app = QApplication(sys.argv)
    mainWin = MainWindow()
    mainWin.show()
    sys.exit(app.exec_())

【问题讨论】:

    标签: python pyqt drawing pyqt5 qpushbutton


    【解决方案1】:

    短解:

    QLine 存储在列表中并重绘:

    class MainWindow(QMainWindow):
        def __init__(self):
            QMainWindow.__init__(self)
    
            self.setMinimumSize(QSize(300, 300)) 
    
            pybutton = QPushButton('button', self)
            pybutton.clicked.connect(self.draw_line)
            pybutton.resize(100,100)
            pybutton.move(0, 0) 
    
            pybutton2 = QPushButton('button2', self)
            pybutton2.clicked.connect(self.draw_line)
            pybutton2.resize(100,100)
            pybutton2.move(200, 0) 
            self.lines = []
    
        def draw_line(self):
            button = self.sender()
            r = button.geometry()
            p1 = QPoint(r.left() + r.width()/2, r.height())
            p2 = p1+QPoint(0, 100)
            line = QLine(p1, p2)
            if line not in self.lines:
                self.lines.append(line)
                self.update()
    
        def paintEvent(self,event):
            QMainWindow.paintEvent(self, event)
            painter = QPainter(self)
            pen = QPen(Qt.red, 3)
            painter.setPen(pen)
            for line in self.lines:
                painter.drawLine(line)
    

    长解:

    这类问题已经被问过无数次了,所以我将花时间扩展并给出问题的一般观点,这样我就不会每次都回答这类问题,所以这个问题 它将被改进和更新。

    paintEvent()是处理Qt进行GUI重绘的方法,这个方法重绘一切,所以绘图不节省内存,所以你必须存储指令并进行绘图 按照这些说明。

    我推荐使用paintEvent() 方法来创建自定义小部件,而不是将执行绘画任务的GUI 作为主要功能,因为这个Qt 提供了QGraphicsViewQGraphicsSceneQGraphicsItems 类。


    使用QPainter 的指令重绘任务如drawLine()fillRect() 等会消耗资源,如果您想进行更高效的实现,最好创建一个QPixmap,您必须随时更新必要的,并使用提到的QPixmappaintEvent() 中重新绘制:

    class MainWindow(QMainWindow):
        def __init__(self):
            QMainWindow.__init__(self)
    
            self.setMinimumSize(QSize(300, 300)) 
    
            pybutton = QPushButton('button', self)
            pybutton.clicked.connect(self.draw_line)
            pybutton.resize(100,100)
            pybutton.move(0, 0) 
    
            pybutton2 = QPushButton('button2', self)
            pybutton2.clicked.connect(self.draw_line)
            pybutton2.resize(100,100)
            pybutton2.move(200, 0)
            self.pixmap = QPixmap(self.size())
            self.pixmap.fill(Qt.transparent)
    
        def draw_line(self):
            button = self.sender()
            r = button.geometry()
            p1 = QPoint(r.left() + r.width()/2, r.height())
            p2 = p1+QPoint(0, 100)
            line = QLine(p1, p2)
    
            p = QPainter(self.pixmap)
            pen = QPen(Qt.red, 3)
            p.setPen(pen)
            p.drawLine(line)
            p.end()
    
            self.update()
    
        def paintEvent(self,event):
            QMainWindow.paintEvent(self, event)
            painter = QPainter(self)
            painter.drawPixmap(QPoint(), self.pixmap)
    
        def resizeEvent(self, event):
            if self.width() > self.pixmap.width() or self.height() > self.pixmap.height():
                pixmap = QPixmap(self.size())
                pixmap.fill(Qt.transparent)
                p = QPainter(pixmap)
                p.drawPixmap(QPoint(), self.pixmap)
                self.pixmap = pixmap
            QMainWindow.resizeEvent(self, event)
    

    【讨论】:

    • 非常感谢,这是一个非常有帮助的答案。我读了很多东西。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-04-05
    • 2019-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-15
    • 2017-06-13
    相关资源
    最近更新 更多