如何在画布的任何位置创建一个可以在画布上的任何位置移动的正方形

Posted

技术标签:

【中文标题】如何在画布的任何位置创建一个可以在画布上的任何位置移动的正方形【英文标题】:How create a square at any position of canvas that can be moved at any position on the canvas 【发布时间】:2020-03-07 07:52:59 【问题描述】:

我在画布中的随机位置创建了一个正方形,但我不知道如何通过将其拖动到所需位置将其移动到画布中的其他位置,请提出一些编辑或新方法来实现建议的任务,我边做边学。

附:附上输出窗口的截图。

import sys
from random import randint
from PyQt5 import QtWidgets
from PyQt5.QtWidgets import QApplication, QMainWindow,QPushButton,QWidget
from PyQt5 import QtGui
from PyQt5.QtCore import QRect,Qt
from PyQt5.QtGui import QPainter,QBrush, QPen
from PyQt5 import QtCore


class Window(QMainWindow):
    def __init__(self):
        super(Window,self).__init__()
        title="TeeSquare"
        left=500
        top=200
        width=500
        height=400
        iconName="square.jpg"
        self.setWindowTitle(title)
        self.setWindowIcon(QtGui.QIcon(iconName))
        self.setGeometry(left, top, width, height)
        self.should_paint_Rect = False
        self.windowcomponents()
        self.initUI()
        self.show()

    def initUI(self):
        if self.should_paint_Rect:
            self.label=QtWidgets.QLabel(self)
            self.label.setText("circle")

    def windowcomponents(self):
        button=QPushButton("Add", self)
        button.setGeometry(QRect(0, 0, 50, 28))
        button.setIcon(QtGui.QIcon("Add.png"))
        button.setToolTip("Create Square")
        button.clicked.connect(self.paintRect)


    def paintEvent(self, event):
        super().paintEvent(event)
        if self.should_paint_Rect:
            painter = QtGui.QPainter(self)
            painter.setRenderHint(QPainter.Antialiasing)
            painter.setPen(QPen(Qt.black, 5, Qt.SolidLine))
            painter.drawRect(randint(0,500), randint(0,500), 100, 100)
            self.initUI()
            self.label.move(60,100)

    def paintRect(self, painter):
        self.should_paint_Rect = True
        self.update()

app = QApplication(sys.argv)
Rect=Window()
Rect.show()
sys.exit(app.exec_())

【问题讨论】:

【参考方案1】:

创建动态元素的逻辑是指示一组特定特征,通过修改这些特征,元素被修改。

在这种情况下,您可以使用正方形的中心、正方形的尺寸等,并且该数据必须通过可以从头开始创建的数据结构来实现,例如通过创建具有以下信息的类矩形,但在 Qt 中没有必要创建该元素,因为它已经存在并且是 QRect。

现在该元素已被识别,您可以创建一个 QRect,其左上角在按下按钮时是随机的,并使用该 QRect 来绘制它。

对于拖动程序是:

获取鼠标点击位置。 验证点击是否在矩形内。 计算相对于矩形的位置。 移动鼠标时,矩形的位置必须根据鼠标按下的位置进行更新。

综合以上几点,解决办法是:

import random
import sys

from PyQt5 import QtCore, QtGui, QtWidgets


class Window(QtWidgets.QMainWindow):
    def __init__(self):
        super(Window, self).__init__()

        self.rect = QtCore.QRect()
        self.drag_position = QtCore.QPoint()

        button = QtWidgets.QPushButton("Add", self)
        button.clicked.connect(self.on_clicked)

        self.resize(640, 480)

    @QtCore.pyqtSlot()
    def on_clicked(self):
        if self.rect.isNull():
            self.rect = QtCore.QRect(
                QtCore.QPoint(*random.sample(range(200), 2)), QtCore.QSize(100, 100)
            )
            self.update()

    def paintEvent(self, event):
        super().paintEvent(event)
        if not self.rect.isNull():
            painter = QtGui.QPainter(self)
            painter.setRenderHint(QtGui.QPainter.Antialiasing)
            painter.setPen(QtGui.QPen(QtCore.Qt.black, 5, QtCore.Qt.SolidLine))
            painter.drawRect(self.rect)

    def mousePressEvent(self, event):
        if self.rect.contains(event.pos()):
            self.drag_position = event.pos() - self.rect.topLeft()
        super().mousePressEvent(event)

    def mouseMoveEvent(self, event):
        if not self.drag_position.isNull():
            self.rect.moveTopLeft(event.pos() - self.drag_position)
            self.update()
        super().mouseMoveEvent(event)

    def mouseReleaseEvent(self, event):
        self.drag_position = QtCore.QPoint()
        super().mouseReleaseEvent(event)


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    Rect = Window()
    Rect.show()
    sys.exit(app.exec_())

【讨论】:

如何为多个对象扩展它?(创建多个正方形并在画布中移动它们) @teecup 逻辑类似:1)创建几个QRect,2)检测鼠标点击是否在一个QRect上,3)移动(2)的QRect。 @teecup 5) 我建议你尝试一些事情(花一些必要的时间:可能一天、两天或一周),只有当没有什么对你有用时,然后发布一个新问题,明确说明你想要什么去做,通过显示证明它的代码来描述你尝试过的事情。考虑到我不会在 cmets 中回答任何问题。 SO 不是 OP 说“给我代码”的 SW 写作服务。我已经指出了具体的步骤,所以你至少应该尝试一下。 我试图创建一个矩形列表来存储 QRect 的每个实例,并在调用 mouseReleaseEvent 时将其附加到列表末尾,但它似乎不起作用。我应该做什么至少请指导我并建议我为此目的所需的文档。我没有找到适当的文档和资源来正确学习,所以你在某种程度上是对的,但我真的很想学习。 @teecup 他的要求永远不会出现在文档中。通过写一个新问题通过展示你尝试过的方法来表明你想学习(我已经在我的第一条评论中指出了这些步骤)。

以上是关于如何在画布的任何位置创建一个可以在画布上的任何位置移动的正方形的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 C# 在画布上的 WPF 中绘制透明 PNG

画布无限滚动映射对象位置

画布旋转后如何检测画布上的点

如何将点击事件绑定到 Tkinter 中的画布? [关闭]

滚动后如何确定光标在画布上的位置?

如何更改D3中饼图的位置?