Pyqt5 在两个小部件之间画一条线 [英] Pyqt5 draw a line between two widgets

查看:329
本文介绍了Pyqt5 在两个小部件之间画一条线的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 QPainter 在两个小部件之间画一条线.如果我在第一个类中使用一个简单的函数,它就可以工作.但是,我想创建一个单独的 QPainter 事件类,我可以随时在第一个类中调用它.但是,它没有按预期工作.你能帮我弄清楚为什么 QPainter 类没有添加一行吗?

I am trying to use QPainter to draw a line between two widgets. If I use a simple function inside the first class it works. But, I want to create a separate class of a QPainter event, that I can call at the first class whenever I want. But, it is not working as expected. Can you help me to figure out why the QPainter class is not adding a line.

import sys
from PyQt5.QtGui     import *
from PyQt5.QtCore    import *
from PyQt5.QtWidgets import *

class Example(QWidget):

    def __init__(self):
        super().__init__()

        self.initUI()


    def initUI(self):

        self.okButton = QPushButton("OK")
        self.cancelButton = QPushButton("Cancel")

        l1 = self.okButton.pos()
        l2 = self.cancelButton.pos()

        # This is to call the class to draw a line between those two widgets
        a = QPaint(l1.x(), l1.y(), l2.x(), l2.y(),parent=self)

        vbox = QVBoxLayout()
        vbox.addWidget(self.okButton)
        vbox.addWidget(self.cancelButton)

        self.setLayout(vbox)    

        self.setGeometry(300, 300, 300, 150)
        self.setWindowTitle('Buttons')    
        self.show()


class QPaint(QPainter):
    def __init__(self, x1, y1, x2, y2, parent=None):
        super().__init__()

    def paintEvent(self, event):

        self.setPen(Qt.red)

        self.drawLine(x1,y1,x2,y2)


if __name__ == '__main__':

    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())

推荐答案

Widgets 只能在widget 的paintEvent 方法中绘制,所以如果不想在同一个类中绘制那么可以使用多重继承.另一方面,您用于绘制的初始位置将是显示它们为 0 之前的位置,因此不会绘制线条而是绘制一个点,因此最好使用事件过滤器跟踪位置.

Widgets can only be painted in the widget's paintEvent method, so if you don't want to paint it in the same class then you can use multiple inheritance. On the other hand, the initial positions you use to paint will be the positions before showing that they are 0 making no line is painted but a point so it is better to track the positions using an event filter.

import sys

from PyQt5.QtCore import QEvent
from PyQt5.QtGui import QPainter
from PyQt5.QtWidgets import QApplication, QPushButton, QVBoxLayout, QWidget


class Drawer:
    def paintEvent(self, event):
        painter = QPainter(self)
        painter.drawLine(self.p1, self.p2)


class Example(QWidget, Drawer):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.initUI()

    def initUI(self):
        self.okButton = QPushButton("OK")
        self.cancelButton = QPushButton("Cancel")

        vbox = QVBoxLayout(self)
        vbox.addWidget(self.okButton)
        vbox.addWidget(self.cancelButton)

        self.setGeometry(300, 300, 300, 150)
        self.setWindowTitle("Buttons")

        self.p1, self.p2 = self.okButton.pos(), self.cancelButton.pos()

        self.okButton.installEventFilter(self)
        self.cancelButton.installEventFilter(self)

    def eventFilter(self, o, e):
        if e.type() == QEvent.Move:
            if o is self.okButton:
                self.p1 = self.okButton.pos()
            elif o is self.cancelButton:
                self.p2 = self.cancelButton.pos()
            self.update()
        return super().eventFilter(o, e)


if __name__ == "__main__":

    app = QApplication(sys.argv)
    ex = Example()
    ex.show()
    sys.exit(app.exec_())

这篇关于Pyqt5 在两个小部件之间画一条线的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆