QPainter 不绘制

QPainter doesn't draw

我正在尝试使用带有变量 self.lines 的 QPainter 绘制一些线条,但它没有这样做。当我尝试绘制其他任何东西时,但我手动传递数字时,一切都很顺利。这是我的代码:

import sys, os
from math import pi
from PyQt5.QtWidgets import (QApplication, QWidget, QPushButton, QMenuBar, QMenu, QAction, QHBoxLayout, QFileDialog)
from PyQt5.QtGui import (QPainter, QPen)
from PyQt5.QtCore import (Qt, QPoint, QLineF)

class MainWindow(QWidget):
    def __init__(self):
        super().__init__()

        self.coords, self.graph, self.used, self.tin, self.fup, self.con_points = [], [], [], [], [], []
        self.num_of_peaks, self.circle_size, self.timer = 0, 40, 0
        self.algo_starts, self.from_file = False, False
        self.graph_config, self.graph_new = None, None

        self.lines = []

        self.setGeometry(300, 300, 1000, 500)
        self.move(QApplication.desktop().screen().rect().center()-self.rect().center())
        self.setWindowTitle("con point")

        self.menubar = QMenuBar(self)
        self.filemenu = self.menubar.addMenu("File")
        self.newfile = self.filemenu.addAction("New")
        self.openfile = self.filemenu.addAction("Open")
        self.savefile = self.filemenu.addAction("Save")
        self.exitfile = self.filemenu.addAction("Exit")

        self.filemenu.triggered[QAction].connect(self.ProcessTrigger)

        self.startalgobtn = QPushButton("Start", self)
        self.startalgobtn.setGeometry(self.width()-self.startalgobtn.width(), self.menubar.height(),self.startalgobtn.width(), self.startalgobtn.height())
        self.startalgobtn.setVisible(False)

        self.exitbtn = QPushButton("Exit", self)
        self.exitbtn.setGeometry(self.width()-self.startalgobtn.width(), self.menubar.height() + self.exitbtn.height(),self.startalgobtn.width(),
                                 self.startalgobtn.height())
        self.exitbtn.setVisible(False)
        self.exitbtn.clicked.connect(self.Exit)

        self.show()

    def ProcessTrigger(self, q):
        if q == self.newfile: self.NewFile()
        if q == self.openfile: self.OpenFile()
        if q == self.savefile: self.SaveFile()
        if q == self.exitfile: self.Exit()

    def paintEvent(self, a0):
        self.paint_teritory = QPainter(self)
        self.paint_teritory.setRenderHint(QPainter.Antialiasing)
        self.paint_teritory.setBackground(Qt.white)
        self.paint_teritory.setBrush(Qt.black)
        self.paint_teritory.setPen(QPen(Qt.black, 2, Qt.SolidLine))
        self.paint_teritory.drawEllipse(40, 40, 40, 40)
        self.paint_teritory.drawLines(self.lines)

        self.paint_teritory.end()

    def NewFile(self):
        return

    def OpenFile(self):
        self.from_file = True
        self.graph_config = QFileDialog.getOpenFileName(self, "Open File", os.getcwd(), "Text Files (*.txt)")[0]
        self.ReadGraph()

    def SaveFile(self):
        return

    def Exit(self): QApplication.instance().quit()

    def ReadGraph(self):
        if self.from_file:
            with open(self.graph_config) as f: self.graph_config = f.readlines()

            self.num_of_peaks = int(self.graph_config[0])
            self.graph = [[] for x in range(self.num_of_peaks)]

            i = 1
            while self.graph_config[i] != "COORDS\n":
                line = self.graph_config[i].split()
                if len(line) == 1: self.graph[int(line[0])-1] = []
                else: self.graph[int(line[0])-1] = sorted(list(map(int, line[1::])))
                i += 1

            i += 1
            for x in range(i, len(self.graph_config)):
                self.coords.append(list(map(int, self.graph_config[i].split())))

        for i in self.graph:
            for j in i:
                self.lines.append(
                    QLineF(QPoint(self.coords[self.graph.index(i)][0], self.coords[self.graph.index(i)][1]),
                           QPoint(self.coords[j - 1][0], self.coords[j - 1][1])))
        self.conf_yes = True

        self.startalgobtn.setVisible(True)
        self.exitbtn.setVisible(True)

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

所以,正如我所说,当我尝试使用 self.lines 绘制时,没有任何反应,但是当我使用 self.paint_teritory.drawEllipse(40, 40, 40, 40) 绘制圆圈时,它确实出现了。

这是我用来测试的文件:https://drive.google.com/file/d/1V4I2okeoE7K_hoClfllYLvFXB78Cjxyh/view?usp=sharing

这就是如何为这个程序制作一个的说明:https://drive.google.com/open?id=1EPxlxUPxH3oWaYJdi9N3RVtC7WPokOCU

问题是您正在生成起点和终点相同的直线,因此这是无效的,PyQt 创建了一个空 QLine。

画线也很费力,在这种情况下最明智的做法是使用 QPainterPath,如下所示:

import sys, os
from math import pi
from PyQt5.QtWidgets import (QApplication, QWidget, QPushButton, QMenuBar, QMenu, QAction, QHBoxLayout, QFileDialog)
from PyQt5.QtGui import (QPainter, QPen, QPainterPath)
from PyQt5.QtCore import (Qt, QPointF, QLineF)

class MainWindow(QWidget):
    def __init__(self):
        super().__init__()

        self.algo_starts, self.from_file = False, False
        self.graph_config, self.graph_new = None, None

        self.paths = []

        self.setGeometry(300, 300, 1000, 500)
        self.move(QApplication.desktop().screen().rect().center()-self.rect().center())
        self.setWindowTitle("con point")

        self.menubar = QMenuBar(self)
        self.filemenu = self.menubar.addMenu("File")
        self.newfile = self.filemenu.addAction("New")
        self.openfile = self.filemenu.addAction("Open")
        self.savefile = self.filemenu.addAction("Save")
        self.exitfile = self.filemenu.addAction("Exit")

        self.filemenu.triggered[QAction].connect(self.ProcessTrigger)

        self.startalgobtn = QPushButton("Start", self)
        self.startalgobtn.setGeometry(self.width()-self.startalgobtn.width(), self.menubar.height(),self.startalgobtn.width(), self.startalgobtn.height())
        self.startalgobtn.setVisible(False)

        self.exitbtn = QPushButton("Exit", self)
        self.exitbtn.setGeometry(self.width()-self.startalgobtn.width(), self.menubar.height() + self.exitbtn.height(),self.startalgobtn.width(),
                                 self.startalgobtn.height())
        self.exitbtn.setVisible(False)
        self.exitbtn.clicked.connect(self.Exit)

        self.show()

    def ProcessTrigger(self, q):
        if q == self.newfile: self.NewFile()
        if q == self.openfile: self.OpenFile()
        if q == self.savefile: self.SaveFile()
        if q == self.exitfile: self.Exit()

    def paintEvent(self, a0):
        painter = QPainter(self)
        painter.setRenderHint(QPainter.Antialiasing)
        painter.setBackground(Qt.white)
        painter.setBrush(Qt.black)
        painter.setPen(QPen(Qt.black, 2, Qt.SolidLine))
        painter.drawEllipse(40, 40, 40, 40)
        painter.setBrush(Qt.NoBrush)
        for path in self.paths:
            painter.drawPath(path)

    def NewFile(self):
        return

    def OpenFile(self):
        self.from_file = True
        self.graph_config = QFileDialog.getOpenFileName(self, "Open File", os.getcwd(), "Text Files (*.txt)")[0]
        self.ReadGraph()

    def SaveFile(self):
        return

    def Exit(self): QApplication.instance().quit()

    def ReadGraph(self):
        if self.from_file:
            with open(self.graph_config) as f: data = f.readlines()
            num_of_peaks, *info = data
            ix = info.index("COORDS\n")
            vertices_raw = info[:ix]
            coords_raw = info[ix+1:]
            vertices = [list(map(int, vertice.split())) for vertice in vertices_raw]
            coords = [list(map(int, coord.split())) for coord in coords_raw] 

            for vertice in vertices:
                path = QPainterPath()
                for i, p in enumerate(vertice):

                    point = QPointF(*coords[i])
                    if i == 0:
                        path.moveTo(point)
                    else:
                        path.lineTo(point)
                self.paths.append(path)

            self.update()

        self.conf_yes = True

        self.startalgobtn.setVisible(True)
        self.exitbtn.setVisible(True)

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