PyQt:如何在控件间传输文本数据?

1 投票
1 回答
1928 浏览
提问于 2025-04-17 06:41

我遇到了一些问题。为了让你们更好地理解,我附上了一张我正在处理的内容的图片。我的图标列表在底部,上面有一个QGraphicsView(中间有一条线穿过)。

http://oi43.tinypic.com/2uhx1xj.jpg(因为我是新手,所以暂时不能发图片)

目前,我可以把底部列表中的图标拖到QGraphicsView里。但是,拖进去的图像只是我定义的一个默认图像,也就是“搅拌机”图标。(下面的代码是我用来处理这个默认图像的)

#Defined in QGraphicScene
def dropEvent(self, event):
    event.accept()
    item = QGraphicsPixmapItem(QPixmap("images/{}".format("blender")))
    item.setFlags(QGraphicsItem.ItemIsSelectable|
                  QGraphicsItem.ItemIsMovable)

    position = QPointF(event.scenePos())
    print(position)
    item.setPos(position)
    self.addItem(item)

我想要的是,拖到QGraphicsView里的图像应该和QListWidget里的图像一致。比如说,如果我把“Mozilla”拖到QGraphicsView里,我希望显示的是Mozilla的图标,其他的也是一样。我觉得如果能把QListWidget里的文本名称传到QGraphicsView里,就可以把“搅拌机”替换成相应的变量。

我认为我需要重新定义QListWidget的“startDrag()”函数,然后在我的QGraphicsScene里实现“dropEvent()”来处理这些数据。我看过QMimeData和QDataStream,但还不是很清楚。我觉得大概是这样的:

#startDrag() that is reimplemented for the listWidget1 function. listWidget1 is the list in the first tab
def scene_startDrag(self, dropActions):
    item = self.listWidget1.selectedItems()
    data = QByteArray()
    stream = QDataStream(data, QIODevice.WriteOnly)
    stream.writeQString(item.text())
    mimeData = QMimeData()
    mimeData.setData("application/x-img", data)
    drag = QDrag(self)
    drag.setMimeData(mimeData)

如果有帮助的话,我在listWidget1里把所有的图标存储在一个叫“nodes”的字典里,字典的键就是列表中显示的名称。所以在listWidget1里,Mozilla的键就是“mozilla”。

简单来说,我只想在QGraphicsView里显示正确的图像。抱歉发了这么长的帖子。有没有人知道我该怎么实现这个?谢谢大家的建议!

1 个回答

2

我本来不觉得能搞定这个问题,但最后还是找到了办法。在仔细研究了一下拖放功能后,我终于弄出了一个可用的方案。QMimeData 这个东西真让人困惑。

这是我做的第一步。我重新实现了列表控件的 startDrag() 方法:

def scene_startDrag(self, dropActions):
    item = self.listWidget1.currentItem()
    data = QByteArray()
    stream = QDataStream(data, QIODevice.WriteOnly)
    stream.writeQString(item.text())
    mimeData = QMimeData()
    mimeData.setData("application/x-imgname", data)
    drag = QDrag(self)
    drag.setMimeData(mimeData)
    drag.exec() #actually starts the dragging

然后在和 QGraphicsView 关联的 QGraphicsScene 中,我重新实现了 dropEvent() 方法:

def dropEvent(self, event):
    if(event.mimeData().hasFormat("application/x-imgname")):
        event.accept()
        data = event.mimeData().data("application/x-imgname")
        stream = QDataStream(data, QIODevice.ReadOnly)
        text = stream.readQString()
        item = QGraphicsPixmapItem(QPixmap("images/{}".format(text)))
        item.setFlags(QGraphicsItem.ItemIsSelectable|
                      QGraphicsItem.ItemIsMovable)
        position = QPointF(event.scenePos())
        item.setPos(position)
        self.addItem(item)

撰写回答