Search code examples
pythonpython-3.xpyqt5qlistwidget

How to transfer items from QListWidget based in one window to another QListWidget based in another window?


That being said, I would like to be able to transfer my items from QListWidget based in one window to another.

The code below allows me to transfer one item at a time, but I am struggling to think of a way to transfer multiple items at one time.

(Code below is from an example I found and have altered.)

from PyQt5.QtWidgets import (
    QApplication,
    QMainWindow,
    QDialog,
    QWidget,
    QVBoxLayout,
    QLineEdit,
    QLabel,
    QPushButton,
    QListWidget,
    QAbstractItemView
    )


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.user_input = QListWidget()
        self.user_input.addItem("2")
        self.user_input.addItem("3")
        self.populate()
        self.show()
        self.user_input.setSelectionMode(QAbstractItemView.ExtendedSelection)

    def populate(self):
        widgets = [QLabel("Insert a number"), self.user_input]
        centralWidget = self.group_widgets(widgets)
        self.setCentralWidget(centralWidget)

    def group_widgets(self, widgets):
        parentWidget = QWidget()
        layout = QVBoxLayout()
        for widget in widgets: layout.addWidget(widget)
        parentWidget.setLayout(layout)
        return parentWidget

    def when_input(self, function):
        #self.user_input.textChanged.connect(function)
        self.user_input.itemClicked.connect(self.printItemText)
        self.user_input.itemClicked.connect(function)
        
    def printItemText(self):
        items = self.user_input.selectedItems()
        x = []
        for i in range(len(items)):
            x.append(str(self.user_input.selectedItems()[i].text()))

        print (x)

class Dialog(QDialog):
    def __init__(self):
        super().__init__()
        self.user_input = QListWidget()
        self.relay_sum = None  # function to relay result of addition
        self.populate()
        self.show()

    def populate(self):
        widgets = self.get_widgets()
        layout = self.get_layout(widgets)
        self.setLayout(layout)

    def get_widgets(self):
        widgets = [
            QLabel("Inserted number"),
            self.user_input,
            ]
        return widgets

    def get_layout(self, widgets):
        layout = QVBoxLayout()
        for widget in widgets: layout.addWidget(widget)
        return layout


def main():
    app = QApplication([])
    mainWindow = MainWindow()
    dialog = Dialog()
    mainWindow.when_input(lambda text: dialog.user_input.addItem(str(text.text())))
    app.exec_()

if __name__ == "__main__":
    main()

Solution

  • When an item is clicked it is also selected so just use the last feature.

    One possible solution is to create a new token that transports the cloned items from the selected items, and then add it to the other QListWidget.

    from PyQt5.QtCore import pyqtSignal
    from PyQt5.QtWidgets import (
        QAbstractItemView,
        QApplication,
        QDialog,
        QLabel,
        QListWidget,
        QMainWindow,
        QVBoxLayout,
        QWidget,
    )
    
    
    class MainWindow(QMainWindow):
        custom_signal = pyqtSignal(list)
    
        def __init__(self):
            super().__init__()
            self.user_input = QListWidget(selectionMode=QAbstractItemView.ExtendedSelection)
            self.user_input.addItem("2")
            self.user_input.addItem("3")
            self.populate()
    
            self.user_input.itemSelectionChanged.connect(self.handle_selection_changed)
    
        def populate(self):
            widgets = [QLabel("Insert a number"), self.user_input]
            centralWidget = self.group_widgets(widgets)
            self.setCentralWidget(centralWidget)
    
        def group_widgets(self, widgets):
            parentWidget = QWidget()
            layout = QVBoxLayout(parentWidget)
            for widget in widgets:
                layout.addWidget(widget)
            return parentWidget
    
        def handle_selection_changed(self):
            items = []
            for item in self.user_input.selectedItems():
                items.append(item.clone())
            self.custom_signal.emit(items)
    
    
    class Dialog(QDialog):
        def __init__(self):
            super().__init__()
            self.user_input = QListWidget()
            self.populate()
    
        def populate(self):
            widgets = self.get_widgets()
            layout = self.get_layout(widgets)
            self.setLayout(layout)
    
        def get_widgets(self):
            widgets = [
                QLabel("Inserted number"),
                self.user_input,
            ]
            return widgets
    
        def get_layout(self, widgets):
            layout = QVBoxLayout()
            for widget in widgets:
                layout.addWidget(widget)
            return layout
    
        def add_items(self, items):
            for item in items:
                self.user_input.addItem(item)
    
    
    def main():
        app = QApplication([])
    
        mainWindow = MainWindow()
        mainWindow.show()
    
        dialog = Dialog()
        dialog.show()
    
        mainWindow.custom_signal.connect(dialog.add_items)
    
        app.exec_()
    
    
    if __name__ == "__main__":
        main()