【问题标题】:Drag and Drop in pyqt4 with modifier keys使用修饰键在 pyqt4 中拖放
【发布时间】: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_())

【问题讨论】:

    标签: python qt qt4 pyqt pyqt4


    【解决方案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 的事情,那就太好了。
    • 我找到了stackoverflow.com/questions/11272951/…,我认为它解释了我想了解的关于@pyqtSlot 的内容。所以在你的例子中没有必要?
    • 不是真的,没有pyqtSlot 也可以工作,你不妨跳过那部分
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-01
    • 1970-01-01
    • 2012-01-14
    • 1970-01-01
    • 1970-01-01
    • 2012-05-31
    相关资源
    最近更新 更多