how to reorder QListView items when the model is QSqlTableModel with drag and drop?

爱⌒轻易说出口 提交于 2021-01-07 02:52:56

问题


i'm working with @eyllanesc answer example and i want to reorder the items i followed many answers in stackoverflow and the qt documentation but i'm not able to make it work, it seems like very hard to reorder items with dragging and droping them.

i did it with QListWidget but not with QListView

here is my code :

import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtSql import *
import sys, os


def create_connection():
    db = QSqlDatabase.addDatabase("QSQLITE")
    db.setDatabaseName("medias.sqlite")
    if not db.open():
        print(db.lastError().text())
        return False

    q = QSqlQuery()
    if not q.exec(
        """
    CREATE TABLE IF NOT EXISTS fichiers (
        id INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE NOT NULL,
        path VARCHAR(300) NOT NULL
    )
    """
    ):
        print(q.lastError().text())
        return False
    print(db.tables())
    return True
class listModel(QSqlTableModel):
    def __init__(self,*args, **kwargs):
        super(listModel, self).__init__(*args, **kwargs)
    # pass
    def ajouter(self, fichier):
        rec = self.record()
        rec.setValue("path", fichier)
        self.insertRecord(-1, rec)
        self.select()


    def flags(self, index):
        defaultFlags = QAbstractItemModel.flags(self, index)
        if not index.isValid():
            return Qt.ItemIsDropEnabled
        if index.row():
            return Qt.ItemIsEnabled | Qt.ItemIsEditable | Qt.ItemIsSelectable | Qt.ItemIsDragEnabled
        else:
            # print('nonononon')
            return Qt.ItemIsEnabled | Qt.ItemIsEditable | Qt.ItemIsSelectable | Qt.ItemIsDragEnabled | defaultFlags
        return Qt.ItemIsEnabled | Qt.ItemIsEditable | Qt.ItemIsSelectable | Qt.ItemIsDragEnabled | defaultFlags
    
    

    # def supportedDropActions(self):
    #     return Qt.MoveAction | Qt.CopyAction

    # def relocateRow(self, row_source, row_target):
    #     row_a, row_b = max(row_source, row_target), min(row_source, row_target)
    #     self.beginMoveRows(QtCore.QModelIndex(), row_a, row_a, QtCore.QModelIndex(), row_b)
    #     self._data.insert(row_target, self._data.pop(row_source))
    #     self.endMoveRows()

class StyledItemDelegate(QStyledItemDelegate):
    def initStyleOption(self, option, index):
        super().initStyleOption(option, index)
        data = str(index.data())
        text = data.split('/')[-1]
        option.text = f"{index.row() + 1} -          {text}"

class MainWindow(QMainWindow):
    def __init__(self, *args, **kwargs):
        super(MainWindow, self).__init__(*args, **kwargs)
        self.play_list = []
        self.setGeometry(900, 180, 800, 600)
        self.setWindowTitle("Media Display")
        self.setWindowIcon(QIcon('favicon.png'))

        self.model = listModel()
        self.model.setTable("fichiers")
        self.model.select()

        self.listview = QListView()
        delegate = StyledItemDelegate(self.listview)
        self.listview.setItemDelegate(delegate)
        self.listview.setModel(self.model)
        self.listview.setModelColumn(1)
        self.listview.setAcceptDrops(True)
        self.listview.setDragEnabled(True)
        self.listview.setDragDropOverwriteMode(True)
        self.listview.viewport().setAcceptDrops(True)
        self.listview.setDropIndicatorShown(True)
        self.listview.setDragDropMode(QAbstractItemView.InternalMove)
        self.init_ui()

    def deleteItem(self):
        current_item = self.listview.selectedIndexes()
        for index in current_item:
            self.model.removeRow(index.row())
            self.model.select()

    def addImage(self):
        fichier_base, _ = QFileDialog.getOpenFileName(
            self, "select video", QDir.homePath(), "Images (*.png *.xpm *.jpg *.jpeg)"
        )

        if fichier_base:
            self.model.ajouter(fichier_base)
            # rec = self.model.record()
            # rec.setValue("path", fichier_base)
            # self.model.insertRecord(-1, rec)
            # self.model.select()
        self.addToPlaylist()
        print(self.play_list)

    def clearDb(self):
        query = QSqlQuery()
        query.exec("DELETE FROM fichiers")
        self.model.select()

    def addToPlaylist(self):
        self.play_list.clear()
        model = self.listview.model()
        for row in range(model.rowCount()):
            index = model.index(row , 1)
            item = model.data(index, Qt.DisplayRole)
            self.play_list.append(item)

    def playPause(self):
        self.addToPlaylist()
        self.addToMedialist()
        self.listPlayer.play()

    def init_ui(self):
        self.add_img_btn = QPushButton("Add image ")
        self.add_img_btn.setFixedWidth(100)
        self.add_img_btn.clicked.connect(self.addImage)
        self.clear_db_btn = QPushButton("clear DB")
        self.clear_db_btn.setFixedWidth(100)
        self.clear_db_btn.clicked.connect(self.clearDb)
        self.refresh_btn = QPushButton("Delete Media")
        self.refresh_btn.setFixedWidth(100)
        self.refresh_btn.clicked.connect(self.deleteItem)

        group_btns = QHBoxLayout()

        main_app = QVBoxLayout()

        main_app.addWidget(self.listview)

        main_app.addLayout(group_btns)

        group_btns.addWidget(self.add_img_btn)
        group_btns.addWidget(self.clear_db_btn)

        widget = QWidget()
        vboxlay = QHBoxLayout(widget)
        vboxlay.addLayout(main_app)

        self.setCentralWidget(widget)


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

    if not create_connection():
        sys.exit(-1)
    window = MainWindow()
    window.setStyleSheet("background-color:#fff;")
    window.show()
    sys.exit(app.exec_()) 

来源:https://stackoverflow.com/questions/65274287/how-to-reorder-qlistview-items-when-the-model-is-qsqltablemodel-with-drag-and-dr

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!