使用修饰键在 pyqt4 中拖放

Posted

技术标签:

【中文标题】使用修饰键在 pyqt4 中拖放【英文标题】:Drag and Drop in pyqt4 with modifier keys 【发布时间】:2012-12-23 16:17:37 【问题描述】:

考虑以下最小示例。当在 drop 事件期间按下修饰键时,我如何修改它,它会执行其他操作,如下面代码中的注释所示。假设您将一个文件从 nautilus 或类似的东西放到我的示例中。

#!/usr/bin/python
# -*- coding: utf-8 -*- 

import sys
from PyQt4.QtGui import *
from PyQt4.QtCore import *

class MyDropLabel(QLabel):
    myDroppedSignal = pyqtSignal(str)    
    myDroppedSignalModified = pyqtSignal()    

    def __init__(self,text):
        super(MyDropLabel, self).__init__(text)
        self.setAcceptDrops(True)

    def dragMoveEvent(self, e):
        e.accept()

    def dragEnterEvent(self, e):
        e.accept()

    def dropEvent(self, e):
        if e.mimeData().hasUrls():
            s = e.mimeData().urls()[0].path()
            self.myDroppedSignal.emit(s)
        e.accept()

##if a modifier key, for example shift or ctrl was pressed to something else and emit myDroppedSignalModified




class MyWidget(QWidget):


    def __init__(self, parent=None):
         QWidget.__init__(self, parent)
         self.hlayout = QHBoxLayout()
         self.setLayout(self.hlayout)
         self.label = MyDropLabel("Drop something here")
         self.hlayout.addWidget(self.label)
         #self.setCentralWidget(self.label)

         self.label.myDroppedSignal.connect(self.myDroppedHandler)

    def myDroppedHandler(self,s):
        self.label.setText(QString(s))

if __name__ == "__main__":
    app = QApplication(sys.argv)
    da = MyWidget()
    da.show()
    sys.exit(app.exec_())

【问题讨论】:

【参考方案1】:

例如,您可以通过installEventFilter( QObject * filterObj ) 设置self.keyIsPressed 状态来过滤您定义的QEvent.KeyPress

这是一个使用QApplication.keyboardModifiers的例子:

#!/usr/bin/env python
#-*- coding:utf-8 -*-

import os

import sip
sip.setapi('QString', 2)
sip.setapi('QVariant', 2)

from PyQt4.QtCore import *
from PyQt4.QtGui import *

class droppableLabel(QLabel):
    fileDropped = pyqtSignal(list)

    def __init__(self, type, parent=None):
        super(droppableLabel, self).__init__(parent)
        self.setAcceptDrops(True)

    def dragEnterEvent(self, event):
        if event.mimeData().hasUrls:
            event.accept()

        else:
            event.ignore()

    def dragMoveEvent(self, event):
        if event.mimeData().hasUrls:
            event.setDropAction(Qt.CopyAction)
            event.accept()

        else:
            event.ignore()

    def dropEvent(self, event):
        if event.mimeData().hasUrls:
            event.setDropAction(Qt.CopyAction)
            event.accept()
            links = []
            for url in event.mimeData().urls():
                links.append(str(url.toLocalFile()))

            self.fileDropped.emit(links)

        else:
            event.ignore()

class droppableWidget(QWidget):
    def __init__(self, parent=None):
        super(droppableWidget, self).__init__(parent)

        self.label = droppableLabel(self)
        self.label.fileDropped.connect(self.on_label_fileDropped)
        self.label.setText("Press CTRL/SHIFT/None and drop some files here")
        self.label.setMinimumSize(QSize(40, 100))

        self.verticalLayout = QVBoxLayout(self)
        self.verticalLayout.addWidget(self.label)
        self.verticalLayout.setMargin(0)

    @pyqtSlot(list)
    def on_label_fileDropped(self, fileNames):
        droppedFiles = [    fileName
                            for fileName in fileNames
                            if os.path.exists(fileName)
                            ]

        if droppedFiles:
            keyModifiers = QApplication.keyboardModifiers()
            if keyModifiers == Qt.ShiftModifier:
                print "SHIFT"
                formatter = "\n"                

            elif keyModifiers == Qt.ControlModifier:
                print "CTRL"
                formatter = ","

            else:
                print "NONE"
                formatter = "|"

            self.label.setText(formatter.join(droppedFiles))

if __name__ == "__main__":
    import  sys

    app = QApplication(sys.argv)
    main = droppableWidget()
    main.show()
    sys.exit(app.exec_())

【讨论】:

谢谢,但我想我需要更多细节,因为我是初学者。你能在我的最小例子中实现你的想法吗? @student checkout my response,我添加了一个示例来说明它 谢谢,我试过了,并根据我的实际代码对其进行了修改,效果很好。由于我是 pyqt4 初学者并且想学习一些新的东西,如果你能在你的例子中更详细地解释 @pyqtSlot 的事情,那就太好了。 我找到了***.com/questions/11272951/…,我认为它解释了我想了解的关于@pyqtSlot 的内容。所以在你的例子中没有必要? 不是真的,没有pyqtSlot 也可以工作,你不妨跳过那部分

以上是关于使用修饰键在 pyqt4 中拖放的主要内容,如果未能解决你的问题,请参考以下文章

需要在icarousel中拖放视图

使用 Dragula 在应用程序中拖放 WebDriver

在 GUI 中拖放

在 UITextView 中拖放时显示文本光标

用于 Silverlight 中拖放的 TranslateTransform

如何使用 jQuery 在 div 中多次拖放图像以及在 drop div 中拖放图像?