简体   繁体   中英

How to call QMainWindow class method from within extended QListWidget class dropEvent?

Here is a working piece of source code. When you run it, simply drag and drop an item from the first listWidget to the second listWidget.

I have a print statement in the dropEvent where I'd like to call the parent QMainWindow's method named "special".

from PyQt4 import QtGui, QtCore
from PyQt4.QtCore import Qt,QString
import sys, os

class ThumbListWidget(QtGui.QListWidget):
    _rows_to_del=[]

    def __init__(self, type, parent=None):
        super(ThumbListWidget, self).__init__(parent)
        self.setIconSize(QtCore.QSize(124, 124))
        self.setDragDropMode(QtGui.QAbstractItemView.DragDrop)
        self.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection)
        self.setAcceptDrops(True)
        self._dropping = False

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

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

    def dropEvent(self, event):

        print "How can I call the main window class method called 'special' here?"

        if event.mimeData().hasUrls():
            event.setDropAction(QtCore.Qt.CopyAction)
            event.accept()
            links = []
            for url in event.mimeData().urls():
                links.append(str(url.toLocalFile()))
            self.emit(QtCore.SIGNAL("dropped"), links)
        else:
            event.setDropAction(QtCore.Qt.CopyAction)
            self._dropping = True
            super(ThumbListWidget, self).dropEvent(event)
            self._dropping = False

    def rowsInserted(self, parent, start, end):
        if self._dropping:
            self.emit(QtCore.SIGNAL("dropped"), (start, end))
        super(ThumbListWidget, self).rowsInserted(parent, start, end)

    def dataChanged(self,start,end):
        if self._dropping:
            for row in range(start.row(),end.row()+1):
                index = self.indexFromItem(self.item(row))
                shot = index.data().toString()
                #print len(self.findItems(shot,Qt.MatchExactly))
                if len(self.findItems(shot,Qt.MatchExactly))>1:
                    self._rows_to_del.append(row)

            self._rows_to_del.reverse()

            for row in self._rows_to_del:
                self.takeItem(row)

            self._rows_to_del=[]

class Dialog_01(QtGui.QMainWindow):
    def __init__(self):
        super(QtGui.QMainWindow,self).__init__()
        self.listItems={}

        myQWidget = QtGui.QWidget()
        myBoxLayout = QtGui.QVBoxLayout()
        myQWidget.setLayout(myBoxLayout)
        self.setCentralWidget(myQWidget)

        self.listWidgetA = ThumbListWidget(self)
        for i in range(12): 
            QtGui.QListWidgetItem( 'Item '+str(i), self.listWidgetA )

        all_items =  self.listWidgetA.findItems(QString('*'), Qt.MatchWrap | Qt.MatchWildcard)
        for item in all_items:
            item.setFlags(item.flags() | Qt.ItemIsUserCheckable )
            # item.setCheckState(Qt.Checked)

        myBoxLayout.addWidget(self.listWidgetA)

        self.listWidgetB = ThumbListWidget(self)

        self.listWidgetA.setAcceptDrops(False)

        myBoxLayout.addWidget(self.listWidgetB)   

        self.connect(self.listWidgetA, QtCore.SIGNAL("dropped"), self.items_dropped)
        self.listWidgetA.currentItemChanged.connect(self.item_clicked)

        self.connect(self.listWidgetB, QtCore.SIGNAL("dropped"), self.items_dropped)
        self.listWidgetB.currentItemChanged.connect(self.item_clicked)

    def items_dropped(self, arg):
        print 'items_dropped', arg
        start,end = arg
        #print range(start,end+1)
        for row in range(start,end+1):
            item = self.listWidgetB.item(row)
            item.setFlags(item.flags() | Qt.ItemIsUserCheckable )
            item.setCheckState(Qt.Checked)

    def special(self):
        print "special called"

    def item_clicked(self, arg):
        print "arg=",arg

if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    dialog_1 = Dialog_01()
    dialog_1.show()
    dialog_1.resize(480,320)
    sys.exit(app.exec_())

In this case, you're passing the window along to the constructor of your custom widget as self , which becomes the parent of your custom widget. So you should just be able to do

window = self.parent()
window.special()

You could also use the Qt event system to emit an event that your main window could connect to and call the special method itself.

class ThumbListWidget(QtGui.QListWidget):
    my_signal = pyqtSignal()

    def dropEvent(self, event):
        self.my_signal.emit()


class Dialog_01(QtGui.QMainWindow):
    def __init__(self):
        ...
        self.listWidgetB = ThumbListWidget(self)
        self.listWidgetB.my_signal.connect(self.special)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM