Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
244 views
in Technique[技术] by (71.8m points)

python - Drag QListWidgetItem out of QListWidget

I would like to drag a QListWidgetItem out of QListWidget. I'm making a program to create a soccer line up by dragging players (label with pixmap) around. I want to drag players from the "bench" to the "outfield", where the user can drag them freely in a soccer formation:

program on start:
program on start

dragging players between the "bench" and the "outfield":
dragging players between the left hand side and the right hand side

I thought about using labels with pixmap for the "outfield" players, but I'm wondering if it's possible to use QListWidgetItem out of QListWidget. Is there a better way to do this?

Code:

import json
import os
import sys

from PyQt5 import QtGui
from PyQt5.Qt import QPixmap
from PyQt5.QtCore import QPoint, Qt, QSize
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QApplication, QLabel, QMainWindow, QListWidget, QListWidgetItem


class MainWindow(QMainWindow):
    def __init__(self, *args, obj=None, **kwargs):
        super(MainWindow, self).__init__(*args, **kwargs)

        class MovableLabel(QLabel):
            """WToolBar is a personalized toolbar."""

            homeAction = None

            oldPos = QPoint()

            def __init__(self, mainWindow : MainWindow, filename: str):
                super().__init__(mainWindow)
                self.mainWindow = mainWindow
                self.filename = filename
                self.clicked = False

            def mousePressEvent(self, evt):
                """Select the toolbar."""
                self.oldPos = evt.globalPos()
                if not self.clicked:
                    globalPos = self.mapToGlobal(self.pos())
                    self.setParent(self.mainWindow)
                    self.move(self.mapFromGlobal(globalPos))
                    self.raise_()
                    self.show()
                    self.clicked = True
                    self.grabMouse()

            def mouseMoveEvent(self, evt):
                """Move the toolbar with mouse iteration."""
                delta = QPoint(evt.globalPos() - self.oldPos)
                self.move(self.x() + delta.x(), self.y() + delta.y())
                self.oldPos = evt.globalPos()

            def mouseReleaseEvent(self, ev: QtGui.QMouseEvent) -> None:
                self.releaseMouse()
                self.clicked = False
                if ev.globalPos().x() < listWidget.width():
                    if self in self.mainWindow.players:
                        self.mainWindow.players.remove(self)
                if self not in self.mainWindow.players:
                    self.mainWindow.players.append(self)

        self.players = []
        pixmap = QPixmap()

        class MyItem(QListWidgetItem):
            def __init__(self, label : MovableLabel):
                super(MyItem, self).__init__()
                self.label = label

        class MyListWidget(QListWidget):
            def __init__(self, mainWindow : MainWindow):
                super(MyListWidget, self).__init__(mainWindow)
                self.mainWindow = mainWindow

            def mouseReleaseEvent(self, e: QtGui.QMouseEvent) -> None:
                item = self.selectedItems()[0]
                imageSize = item.icon().actualSize(QSize(100, 200))
                self.removeItemWidget(item)
                label = MovableLabel(self.mainWindow, 'Pogba.jpg')
                pixmap = item.icon().pixmap(imageSize)
                label.setPixmap(pixmap)
                label.setFixedSize(imageSize)
                label.move(e.globalPos())
                label.show()

        listWidget = MyListWidget(self)
        listWidget.setViewMode(QListWidget.IconMode)
        listWidget.setFixedSize(500, 700)
        listWidget.setIconSize(QSize(100, 200))
        listWidget.setDragDropMode(listWidget.InternalMove)


        '''json file contains positions of "outfield" players'''
        try:
            with open('players.txt', 'r') as file:
                data = json.load(file)
        except:
            data = []

        dir = 'Players/'

        for filename in os.listdir(dir):
            pixmap = QPixmap(dir + filename).scaledToHeight(100, Qt.SmoothTransformation)
            label = MovableLabel(self, filename)
            label.setPixmap(pixmap)
            label.setFixedSize(pixmap.width(), pixmap.height())

            playersIndex = next((i for i, player in enumerate(data) if player['filename'] ==
                                 filename), None)
            if playersIndex == None:
                item = QListWidgetItem(QIcon(dir + filename), '<Name>', listWidget)
            else:
                label.setParent(self)
                label.move(data[playersIndex]['x'], data[playersIndex]['y'])
                self.players.append(label)
        self.setStyleSheet("background-color: black;")
        self.showMaximized()

    def closeEvent(self, a0: QtGui.QCloseEvent) -> None:
        with open('players.txt', 'w') as outfile:
            json.dump([{'filename': player.filename, 'x': player.x(), 'y': player.y()} for player in self.players],
                      outfile, indent= 4)


if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = MainWindow()
    app.exec_()

Edit:

I've tried to implement using label with pixmap when dragging the QListWidgetItem out the QListWidget, but the listWidgetItem won't disappear from the listWidget, I can't get the label to align with the item as it were it (I just moved the label to where the cursor is), and I'm unsure how to replace the player to the listWidget. What event is triggered when the item is dragged out the listWidget? Any feedback would be much appreciated.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)
等待大神答复

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...