2017-02-13 47 views
1

我有一組3個列表小部件,都具有拖放功能。我正在尋找消除重複的代碼,並尋求一些幫助。正如你可以在我的Dialog類中看到的那樣,我創建了3個拖放和drog列表的圖像類。截至目前,每個List Widget都對應一個連接功能。PyQt:參數化連接功能

self.connect(self.one, SIGNAL("dropped"), self.oneDropped)

在我看來,該功能def oneDropped()可以變成一個函數,其中self.oneDropped一種說法,但我有麻煩設置,並可以使用一些幫助。這是我的代碼。

我只用了幾周的Python工作,所以如果這是一個簡單的問題,我很抱歉。

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

class Image(QListWidget): 
    def __init__(self, type, parent=None): 
     super(Image, self).__init__(parent) 
     self.setAcceptDrops(True) 
     self.setIconSize(QSize(72, 72)) 

    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.emit(SIGNAL("dropped"), links) 
     else: 
      event.ignore() 

class Dialog(QDialog): 
    def __init__(self, parent=None): 
     super(Dialog, self).__init__(parent) 

     self.ui = uic.loadUi('./qt/default.ui', self) 

     self.one = Image(self) 
     self.two = Image(self) 
     self.three = Image(self) 
     self.connect(self.one, SIGNAL("dropped"), self.oneDropped) 
     self.connect(self.two, SIGNAL("dropped"), self.twoDropped) 
     self.connect(self.three, SIGNAL("dropped"), self.threeDropped) 
     self.baseimage_layout.addWidget(self.one) 
     self.redimage_layout.addWidget(self.two) 
     self.greenimage_layout.addWidget(self.three) 


    def oneDropped(self, l): 
     for url in l: 
      if os.path.exists(url): 
       print(url) 
       icon = QIcon(url) 
       pixmap = icon.pixmap(72, 72) 
       icon = QIcon(pixmap) 
       item = QListWidgetItem(url, self.one) 
       item.setIcon(icon) 

    def twoDropped(self, l): 
     for url in l: 
      if os.path.exists(url): 
       print(url) 
       icon = QIcon(url) 
       pixmap = icon.pixmap(72, 72) 
       icon = QIcon(pixmap) 
       item = QListWidgetItem(url, self.two) 
       item.setIcon(icon) 

    def threeDropped(self, l): 
     for url in l: 
      if os.path.exists(url): 
       print(url) 
       icon = QIcon(url) 
       pixmap = icon.pixmap(72, 72) 
       icon = QIcon(pixmap) 
       item = QListWidgetItem(url, self.three) 
       item.setIcon(icon) 

def main(): 
    app = QApplication(sys.argv) 
    form = Dialog() 
    form.show() 
    app.exec_() 

if __name__=="__main__": 
    main() 

回答

0

首先,您使用舊式的信號和插槽,它們已經過時,並且在更新版本的PyQt中被刪除。如果可能,您應該使用new-style mechanism

你的榜樣將成爲:

self.one.dropped.connect(self.oneDropped) 

要回答你的問題,在Python中,你可以使用一個lambda expression添加額外的參數時,槽被調用。

首先,您將定義一個通用處理函數,它將Image實例作爲參數。

def imgDropped(self, l, img): 
    for url in l: 
     if os.path.exists(url): 
      print(url) 
      icon = QIcon(url) 
      pixmap = icon.pixmap(72, 72) 
      icon = QIcon(pixmap) 
      item = QListWidgetItem(url, img) 
      item.setIcon(icon) 

然後將信號連接這樣

self.one.dropped.connect(lambda l: self.imgDropped(l, self.one)) 
self.two.dropped.connect(lambda l: self.imgDropped(l, self.two)) 
self.three.dropped.connect(lambda l: self.imgDropped(l, self.three)) 

如果你不熟悉的lambda表達式,像這樣使用時,他們可以是一個強大的工具,但由於變量late binding可能產生意外的行爲提防。

+0

我接受了其他答案,因爲它似乎與我目前的設置很好。話雖如此,你的答案似乎更現代化。我仍在閱讀如何實施新風格。 您對lambda的反應是對新型機制的單獨解決方案,還是打算使用過時的代碼? 再次道歉,如果這是一個簡單的問題。 –

+0

它也應該使用舊的機制。只需用lambda表達式替換'self.oneDropped'等參考。 – user3419537

+0

啊我現在看到了,謝謝! –

0

您可以包括丟棄的功能及其在圖像類信號,這樣你就不必再重複這個功能對於每個類,這裏​​有一個例子:

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

class Image(QListWidget): 
    def __init__(self, type, parent=None): 
     super(Image, self).__init__(parent) 
     self.setAcceptDrops(True) 
     self.setIconSize(QSize(72, 72)) 
     self.connect(self, SIGNAL("dropped"), self.onDropped) 

    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.emit(SIGNAL("dropped"), links) 
     else: 
      event.ignore() 

    def onDropped(self, l): 
     for url in l: 
      if os.path.exists(url): 
       print(url) 
       icon = QIcon(url) 
       pixmap = icon.pixmap(72, 72) 
       icon = QIcon(pixmap) 
       item = QListWidgetItem(url, self) 
       item.setIcon(icon) 

class Dialog(QDialog): 
    def __init__(self, parent=None): 
     super(Dialog, self).__init__(parent) 

     self.ui = uic.loadUi('./qt/default.ui', self) 

     self.one = Image(self) 
     self.two = Image(self) 
     self.three = Image(self) 
     self.baseimage_layout.addWidget(self.one) 
     self.redimage_layout.addWidget(self.two) 
     self.greenimage_layout.addWidget(self.three) 


def main(): 
    app = QApplication(sys.argv) 
    form = Dialog() 
    form.show() 
    app.exec_() 

if __name__=="__main__": 
    main() 
+0

將所有內容移動到Image類中是很好的,但是信號的重點是什麼?你也可以將'onDropped'代碼移動到'dropEvent'中,並將它重構爲單個循環。 – ekhumoro

+0

我同意你的看法,我試圖保持接近實現,也許他會需要這個特定信號從其他地方發射。 – SyedElec