【问题标题】:create a Qt display [closed]创建一个Qt显示[关闭]
【发布时间】:2020-12-17 21:30:22
【问题描述】:

我正在制作一个将在字段中使用箭头的项目,如下所示。

我希望对象在接收到一些移动数据(例如来自卫星的坐标)时移动。

问题是:

  • 如何创建对象箭头?
  • 我应该使用哪些库?我应该使用 QGraphicsScene 类来移动它吗?

我从来没有使用过这种类型的 Qt 对象。我开始使用 PyQt5 在 Python 中进行编码,但由于缺乏使用这种语言的库的示例 - 我开始学习 C++ 以更好地理解 Qt5 库。

【问题讨论】:

  • 它当然可以在 PyQt 中完成,但你的问题有点在“基于意见”的边缘(这通常会导致 StackOverflow 上的一个封闭问题)。根据需要,您可以选择实现自定义绘画的 QWidget 子类,或使用图形项作为抽象层的 QGraphicsView。建议你对它们都做一些研究,自己做一些测试,学习一下它们的对应能力,这样你就可以自己决定了。
  • 谢谢你让我的问题变得更好

标签: python pyqt pyqt5 qgraphicsview qgraphicsscene


【解决方案1】:

Qt 的优势在于它允许您使用低级工具(如 QPainter)到高级工具(如 QGraphicsItem、QML 项)来创建视觉元素。在这种情况下,最简单的方法是使用基于 QGraphicsPathItem 的 QGraphicsItem 并重写 paint 方法进行自定义绘画。对于移动的情况,您只需要使用 setPos() 方法,但要获得平滑的移动,则必须使用 QVariantAnimation。

import random

from PyQt5 import QtCore, QtGui, QtWidgets


class ArrowItem(QtWidgets.QGraphicsPathItem):
    def __init__(self, parent=None):
        super().__init__(parent)
        self._length = -1
        self._points = QtCore.QPointF(), QtCore.QPointF(), QtCore.QPointF()

        self.length = 40.0

    @property
    def length(self):
        return self._length

    @length.setter
    def length(self, l):
        self._length = l

        pos_top = QtCore.QPointF(0, l * 4 / 5)
        pos_left = QtCore.QPointF(-l * 3 / 5, -l / 5)
        pos_right = QtCore.QPointF(
            l * 3 / 5,
            -l / 5,
        )

        path = QtGui.QPainterPath()
        path.moveTo(pos_top)
        path.lineTo(pos_right)
        path.lineTo(pos_left)

        self.setPath(path)

        self._points = pos_top, pos_left, pos_right

    def paint(self, painter, option, widget):

        pos_top, pos_left, pos_right = self._points

        left_color = QtGui.QColor("#cc0000")
        right_color = QtGui.QColor("#ff0000")
        bottom_color = QtGui.QColor("#661900")

        path_left = QtGui.QPainterPath()
        path_left.lineTo(pos_top)
        path_left.lineTo(pos_left)

        path_right = QtGui.QPainterPath()
        path_right.lineTo(pos_top)
        path_right.lineTo(pos_right)

        path_bottom = QtGui.QPainterPath()
        path_bottom.lineTo(pos_left)
        path_bottom.lineTo(pos_right)

        painter.setPen(QtGui.QColor("black"))
        painter.setBrush(left_color)
        painter.drawPath(path_left)
        painter.setBrush(right_color)
        painter.drawPath(path_right)
        painter.setBrush(bottom_color)
        painter.drawPath(path_bottom)

    def moveTo(self, next_position, duration=100):
        self._animation = QtCore.QVariantAnimation()
        self._animation.setStartValue(self.pos())
        self._animation.setEndValue(next_position)
        self._animation.setDuration(duration)
        self._animation.start(QtCore.QAbstractAnimation.DeleteWhenStopped)
        self._animation.valueChanged.connect(self.setPos)


class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.scene = QtWidgets.QGraphicsScene()
        view = QtWidgets.QGraphicsView()
        view.setRenderHints(QtGui.QPainter.Antialiasing)
        view.setScene(self.scene)
        view.scale(1, -1)
        button = QtWidgets.QPushButton("Click me")

        central_widget = QtWidgets.QWidget()
        lay = QtWidgets.QVBoxLayout(central_widget)
        lay.addWidget(view)
        lay.addWidget(button)
        self.setCentralWidget(central_widget)
        self.resize(640, 480)

        self.arrow_item = ArrowItem()
        self.scene.addItem(self.arrow_item)

        button.clicked.connect(self.handle_clicked)

    def handle_clicked(self):
        x, y = random.sample(range(300), 2)
        print("next position:", x, y)
        self.arrow_item.moveTo(QtCore.QPointF(x, y))


if __name__ == "__main__":
    app = QtWidgets.QApplication([])

    w = MainWindow()
    w.show()

    app.exec_()

注意:PyQt5(还有 PySide2)提供了许多用 python 编写的示例,这些示例是 C++ 示例的翻译,因此我建议您下载源代码(PyQt5PySide2)并研究它们。我也有a repo 翻译了一些例子。

【讨论】:

  • eyllanesc,非常感谢!你总是帮助我!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-03
  • 1970-01-01
  • 1970-01-01
  • 2021-05-04
  • 1970-01-01
  • 2012-06-29
相关资源
最近更新 更多