【问题标题】:is it possible to reorder QSqlTableModel from QListView?是否可以从 QListView 重新排序 QSqlTableModel?
【发布时间】:2021-03-28 01:40:39
【问题描述】:

我正在尝试从 QListView 重新排序此 QSqlTableModel 但似乎不可能我尝试了我在互联网上找到的所有东西(官方文档、示例论坛博客)但没有发生任何事情,我激活了移动操作并覆盖标志方法 mimeData 方法,老实说,我不知道我是否做得对。拖动动作有效,但我认为问题在于拖动。

这是我的高级程序

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)
        self.setEditStrategy(QSqlTableModel.OnFieldChange)
        print('mimetype', self.mimeTypes())
        self.setTable("fichiers")
        self.select()

    def flags(self, index):
        return Qt.ItemIsEditable | Qt.ItemIsDragEnabled | Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsDropEnabled

    def ajouter(self, fichier):
        rec = self.record()
        rec.setValue("path", fichier)
        self.insertRecord(-1, rec)
        self.select()

    def mimeData(self, indexes):
        types = self.mimeTypes()
        mimeData = QMimeData()
        print('mimedata', mimeData)
        encodedData = QByteArray()
        stream = QDataStream(encodedData, QIODevice.WriteOnly)
        for index in indexes:
            if not index.isValid():
                continue
            if index.isValid():
                node = index.internalPointer()
                text = self.data(index, Qt.DisplayRole)
        mimeData.setData(types[0], encodedData)
        return mimeData

    def supportedDragActions(self):
        return Qt.MoveAction

    def supportedDropActions(self):
        return Qt.MoveAction 

    def dropMimeData(self, data, action, row, column, parent):
        if action == Qt.MoveAction:
            print ("Moving")
            self.insertRows(row, 1, QModelIndex())
            idx = self.index(row, 0, QModelIndex())
            self.setData(idx, self.mimeTypes())
            return True
        if row != -1:
            beginRow = row
        elif parent.isValid():
            beginRow = parent.row()
        else:
            beginRow = rowCount(QModelIndex())
        

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.setGeometry(900, 180, 800, 600)
        self.setWindowTitle("Media Display")
        self.setWindowIcon(QIcon('favicon.png'))

        self.model = listModel()
        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.setSelectionMode(QAbstractItemView.ExtendedSelection)
        self.listview.setDropIndicatorShown(True)
        self.listview.setDragDropMode(QAbstractItemView.InternalMove)
        self.init_ui()

    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)

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

    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)

        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_()) 

【问题讨论】:

标签: python pyqt pyqt5 qsqltablemodel


【解决方案1】:

我讨厌成为“那个人”,但是……你真正期望能够做什么,在这里?

QSQLTableModel 是 SQL 表的表示形式,它具有特定的顺序。您可以以不同的方式排序记录(使用.sort(),或者,如果您需要更复杂的东西,可以通过 QSortFilterProxyModel 管道)。但是,实现任意排序,您可以将元素拖放到不同的位置,这并不是我期望能够使用 SQL 表完成的事情。如果您真的需要类似的东西,您可能必须实现自己的自定义模型,在该模型上“加载”从 sql 获取的数据,然后您自己管理。在那里您可以实现自己的排序方案,您可以从视图中对其进行操作。

【讨论】:

  • 感谢您的回复,那么您认为获取数据将其放在列表中,然后将其显示在 QListWidget 上会更容易吗?
  • 如果你必须能够以任意顺序重新排列它,可能是的。
猜你喜欢
  • 2018-06-19
  • 2019-12-04
  • 1970-01-01
  • 1970-01-01
  • 2011-01-02
  • 2016-12-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多