绘制线:检索覆盖的像素

时间:2016-07-18 21:17:18

标签: pyqt pyqt4

我想在小部件上画一条线:

from PyQt4 import QtGui, QtCore

class LineLabel(QtGui.QLabel):

    def __init__(self,parent=None):
        super(LineLabel,self).__init__(parent)
        self.setMinimumSize(100,100)
        self.setMaximumSize(100,100)

    def paintEvent(self,e):
        painter=QtGui.QPainter(self)
        pen = QtGui.QPen()
        pen.setWidth(5)
        painter.setPen(pen)
        painter.drawLine(10,10,90,90)
        painter.end()

def test():
    form = QtGui.QWidget()
    label = LineLabel(form)
    form.show()
    return form

import sys
app = QtGui.QApplication(sys.argv)
window =test()
sys.exit(app.exec_())

获取线条所涵盖的像素列表的最佳方法是什么?

从评论中更新:

  • 我不需要直接知道起点和终点之间的像素,而是所有那些变为黑色的像素(由于线条具有一定的宽度,因此更多像素)。
  • 我的总体目标是快速了解窗口小部件上的哪些像素为黑色。迭代图像的像素并查询颜色比从存储颜色的列表中读取颜色值要慢得多:对于包含100万个条目的列表,对于100万像素到0.23秒的图像,对我来说为1.9秒。因此,我必须在每次更改窗口小部件上的图像后更新该列表,例如通过画线。
  • 在QGraphicsScene中引用QGraphicsItem的答案也很有帮助。

1 个答案:

答案 0 :(得分:0)

您可以使用线性方程式在线条中找到所需的点。我认为没有提及画线。

from PyQt4 import QtGui
from PyQt4.QtGui import QColor, QPaintEvent

m_nInitialX = 0.0
m_nInitialY = 0.0


# my line abstraction
class MyLine:
    x1, y1, x2, y2 = .0, .0, .0, .0
    width = .0
    px, py = (.0, .0)
    draw_point = False

    def __init__(self, x1, y1, x2, y2, width):
        self.x1, self.y1, self.x2, self.y2 = (x1, y1, x2, y2)
        self.width = width

    def is_in_line(self, x, y):
        # mark a position in the line
        m = (self.y2 - self.y1) / (self.x2 - self.x1)
        print(m*(x-self.x1)-(y-self.y1))
        if abs((m*(x-self.x1) - (y-self.y1))) <= self.width/2:
            self.draw_point = True
            return True
        else:
            return False

    def add_red_point(self, x, y):
        self.px, self.py = (x, y)

    def draw(self, widget):
        painter = QtGui.QPainter(widget)
        pen = QtGui.QPen()
        pen.setWidth(self.width)
        painter.setPen(pen)
        painter.drawLine(self.x1, self.y1, self.y2, self.y2)

        if self.draw_point:
            pen.setColor(QColor(255, 0, 0))
            painter.setPen(pen)
            painter.drawPoint(self.px, self.py)
        painter.end()


line = MyLine(10, 10, 90, 90, width=10)  # <-- my line abstraction


class LineLabel(QtGui.QLabel):

    def __init__(self, parent=None):
        super(LineLabel, self).__init__(parent)
        self.setMinimumSize(100, 100)
        self.setMaximumSize(100, 100)

    # always redraw when needed
    def paintEvent(self, e):
        print("draw!")
        line.draw(self)

    def mousePressEvent(self, event):
        # mark clicked position in line
        m_nInitialX = event.pos().x()
        m_nInitialY = event.pos().y()
        if line.is_in_line(m_nInitialX, m_nInitialY):
            line.add_red_point(m_nInitialX, m_nInitialY)
            self.repaint()


def test():
    form = QtGui.QWidget()
    label = LineLabel(form)
    form.show()
    return form

import sys

app = QtGui.QApplication(sys.argv)
window = test()
sys.exit(app.exec_())