首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Qt:如何使用自定义模型在QListView中实现简单的内部拖放来对项目进行重新排序

Qt是一种跨平台的C++应用程序开发框架,它提供了丰富的工具和库,用于开发图形用户界面(GUI)应用程序。在Qt中,可以使用自定义模型来实现在QListView中进行简单的内部拖放来对项目进行重新排序。

要实现这个功能,可以按照以下步骤进行操作:

  1. 创建自定义模型:继承自QAbstractListModel,并实现必要的方法,如rowCount()、data()、setData()等。在模型中,可以使用一个列表来存储项目的数据。
  2. 创建QListView对象:在应用程序的界面中创建一个QListView对象,并设置其模型为自定义模型。
  3. 实现拖放功能:为QListView对象启用拖放功能,可以通过设置setDragEnabled()和setAcceptDrops()方法来实现。同时,还需要实现dragEnterEvent()、dragMoveEvent()、dropEvent()等事件处理方法,以处理拖放操作。
  4. 实现重新排序:在自定义模型中,可以添加一个方法来处理项目的重新排序。该方法可以接受源索引和目标索引作为参数,并在内部进行数据的重新排序。在dropEvent()方法中,可以调用该方法来实现项目的重新排序。

以下是一个简单的示例代码,演示了如何使用自定义模型在QListView中实现简单的内部拖放来对项目进行重新排序:

代码语言:txt
复制
#include <QtWidgets>

class CustomModel : public QAbstractListModel
{
public:
    CustomModel(QObject *parent = nullptr)
        : QAbstractListModel(parent)
    {
        m_data << "Item 1" << "Item 2" << "Item 3" << "Item 4" << "Item 5";
    }

    int rowCount(const QModelIndex &parent = QModelIndex()) const override
    {
        return m_data.count();
    }

    QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override
    {
        if (!index.isValid() || index.row() >= m_data.count())
            return QVariant();

        if (role == Qt::DisplayRole)
            return m_data[index.row()];

        return QVariant();
    }

    Qt::ItemFlags flags(const QModelIndex &index) const override
    {
        if (!index.isValid())
            return Qt::NoItemFlags;

        return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled;
    }

    bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override
    {
        if (index.isValid() && role == Qt::EditRole)
        {
            m_data[index.row()] = value.toString();
            emit dataChanged(index, index);
            return true;
        }

        return false;
    }

    Qt::DropActions supportedDropActions() const override
    {
        return Qt::MoveAction;
    }

    bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex()) override
    {
        beginInsertRows(parent, row, row + count - 1);
        for (int i = 0; i < count; ++i)
            m_data.insert(row, "");
        endInsertRows();
        return true;
    }

    bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()) override
    {
        beginRemoveRows(parent, row, row + count - 1);
        for (int i = 0; i < count; ++i)
            m_data.removeAt(row);
        endRemoveRows();
        return true;
    }

    Qt::DropActions supportedDragActions() const override
    {
        return Qt::MoveAction;
    }

    QStringList mimeTypes() const override
    {
        return QStringList() << "text/plain";
    }

    QMimeData *mimeData(const QModelIndexList &indexes) const override
    {
        QMimeData *mimeData = new QMimeData();
        QByteArray encodedData;

        QDataStream stream(&encodedData, QIODevice::WriteOnly);
        for (const QModelIndex &index : indexes)
        {
            if (index.isValid())
            {
                QString text = data(index, Qt::DisplayRole).toString();
                stream << text;
            }
        }

        mimeData->setData("text/plain", encodedData);
        return mimeData;
    }

    bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) override
    {
        if (action == Qt::IgnoreAction)
            return true;

        if (!data->hasFormat("text/plain"))
            return false;

        if (column > 0)
            return false;

        int beginRow;

        if (row != -1)
            beginRow = row;
        else if (parent.isValid())
            beginRow = parent.row();
        else
            beginRow = rowCount(QModelIndex());

        QByteArray encodedData = data->data("text/plain");
        QDataStream stream(&encodedData, QIODevice::ReadOnly);

        QStringList newItems;
        int rows = 0;

        while (!stream.atEnd())
        {
            QString text;
            stream >> text;
            newItems << text;
            ++rows;
        }

        if (rows == 0)
            return false;

        insertRows(beginRow, rows, QModelIndex());

        for (const QString &text : newItems)
        {
            QModelIndex index = createIndex(beginRow++, 0);
            setData(index, text);
        }

        return true;
    }

private:
    QStringList m_data;
};

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    QListView listView;
    CustomModel model;
    listView.setModel(&model);
    listView.setDragEnabled(true);
    listView.setAcceptDrops(true);
    listView.setDropIndicatorShown(true);
    listView.setDefaultDropAction(Qt::MoveAction);
    listView.setSelectionMode(QAbstractItemView::SingleSelection);
    listView.setDragDropMode(QAbstractItemView::InternalMove);

    listView.show();

    return app.exec();
}

在这个示例中,我们创建了一个CustomModel类,继承自QAbstractListModel,并实现了必要的方法来支持自定义模型。然后,我们创建了一个QListView对象,并将其模型设置为自定义模型。通过设置相应的属性和方法,我们启用了拖放功能,并实现了项目的重新排序。

这只是一个简单的示例,你可以根据实际需求进行扩展和修改。对于更复杂的应用场景,可能需要使用更高级的模型类,如QStandardItemModel或QSqlTableModel。

对于腾讯云相关产品和产品介绍链接地址,由于要求不能提及具体的云计算品牌商,我无法给出具体的链接。但是,腾讯云提供了丰富的云计算服务,包括云服务器、云数据库、云存储等,你可以在腾讯云官方网站上找到相关的产品和文档。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

C++ Qt开发:StringListModel字符串列表映射组件

Qt 是一个跨平台C++图形界面开发库,利用Qt可以快速开发跨平台窗体应用程序,Qt我们可以通过拖拽方式将不同组件放到指定位置,实现图形化开发极大方便了开发效率,本章将重点介绍QStringListModel...QStringListModel 是 Qt 中用于处理字符串列表数据模型类之一,它是 QAbstractListModel 子类,用于 Qt 视图类(如 QListView、QComboBox...该组件是用于Qt快速显示字符串列表便捷模型类。...然后,通过 ui->listView->setModel(model) 将模型设置到 QListView ,从而使模型数据 QListView 显示。...这样,通过这两个按钮点击事件,可以向 QStringListModel 添加或插入数据,并在 QListView进行显示。

15010

Qt Designer基本控件介绍——Item Views(表项视图)和Item Widgets(部件)

---- 两者区别: Item Views(Model-Based)对象进行数据操作相对比较复杂,但处理及展示大数据量时性能高; Item Widgets数据操作比较简单,但处理及展示大数据量时性能相对低...Item Widgets开发没有Item Views灵活,实际上Item Widgets就是Item Views基础上绑定了一个默认存储并提供了相关方法。...),操作方便,直接调用addItem即可添加项目(ICON,文字) 详细介绍可以看博客 “Qt入门-列表框QListWidget类” “Qt5.9控件listWidget用法(QListWidget基本用法...,用于应用程序实现撤消/重做功能。...详细介绍可看博客: “实战PyQt5: 078-撤销命令视图QUndoView” “Qt如何实现QTableView撤消与恢复功能”

5.9K00

Qt Style Sheet实践(二):组合框QComboBox定制

这篇博文重点讲述如何用QSS组合框进行定制。 基本自定义      组合框使用非常简单,为了加快叙述速度,我们直接在Qt Designer一个QComboBox控件放到主窗口中。...显然,下拉框选项高度太小了,看起来挺别扭。那么如何下拉框进行定制呢?我们有个很好模仿对象: ?      360安全卫士登录框下拉框看起来就挺不错,而且还有图标出现在选项右边。...看看又该如何进行改进。 高级自定义      要实现上述效果,我们首先要做就是将QComboBox设置为可以编辑(setEditable())。这样,文本框内容才可以手动进行输入。...这样,当用户点击了选项某一个选项时,能够QComboBox文本框显示选中项。那么,QSS该如何编写呢?...QListView::item:hover { background: #BDD7FD; }   也很简单,只是设置了选项高度,和QComboBox高度保持一致,这样看起来不至于别扭。

7.4K70

Python Qt GUI设计:QTableView、QListView、QListWidet、QTableWidget、QTreeWidget和QTreeWidgetltem表格和树类(提升篇—1)

QtableView可以使用自定义数据模型来显示内容,通过setModel来绑定数据源。...QTableWidget继承自QTableView,主要区别是QTableView可以使用自定义数据模型来显示内容(先要通过setModel来绑定数据源),而QTableWidget只能使用标准数据模型...QListView常用方法如下表所示: QListView常用信号如下表所示: 通过示例了解QListView使用方法,效果如下所示: 示例,将QListView控件clicked...信号与自定义对象clicked()槽函数进行绑定,当单击QListView控件里Model一项时会弹出消息框(提示选择是哪─项)。...控件itemClicked信号与自定义对象Clicked()槽函数进行绑定,当单击QListWidget列表一个条目时会弹出消息框,提示选择是哪个条目。

3.8K30

Python Qt GUI设计:QTableView、QListView、QListWidet、QTableWidget、QTreeWidget和QTreeWidgetltem表格和树类(提升篇—1)

QtableView可以使用自定义数据模型来显示内容,通过setModel来绑定数据源。...QTableWidget继承自QTableView,主要区别是QTableView可以使用自定义数据模型来显示内容(先要通过setModel来绑定数据源),而QTableWidget只能使用标准数据模型...QListView常用方法如下表所示: QListView常用信号如下表所示: 通过示例了解QListView使用方法,效果如下所示: 示例,将QListView控件clicked...信号与自定义对象clicked()槽函数进行绑定,当单击QListView控件里Model一项时会弹出消息框(提示选择是哪─项)。...控件itemClicked信号与自定义对象Clicked()槽函数进行绑定,当单击QListWidget列表一个条目时会弹出消息框,提示选择是哪个条目。

3K20

Qt Model View 预定义模型(二)

上次和大家分享不区分模型和视图带来方便情况下,可以直接使用Qt项视图中简便子类,如QListWidget、QTableWidget、QTreeWidget等。...本次和大家分享下如何使用Qt预定义一些模型。...首先了解下几种预定义模型: QStringListModel用于存储QString项简单列表QStandardItemModel管理更复杂项目树结构,每个项目都可以包含任意数据QFileSystemModel...后来比较直观项目中用到了QListView做了一个简单文件显示系统,结合QFile可以新建文件、删除文件、编辑文件等,算是简单使用了一次Model/View。...这次要给大家展示是对于同一个数据源,使用相同Model读取数据,通过将该模型注册到不同View,所展现效果。以及对于同一个数据源使用不同Model,注册到View效果。

1.4K30

Qt ListView 配合Model 显示文件与删除文件

这种方式非常符合直观感受,然而,许多复杂应用,这将导致数据同步问题。第二种方式是模型/视图编程,窗口部件无需维护内部数据容器。它们通过标准接口获取外部数据,也因此避免了数据重复。...(翻译自Model/View Tutorial,具体更多信息可参见QtModel/View Tutorial) 这次要和大家分享QListView,它为模型提供列表或图标视图。...QListView类是Model / View Classes之一,是Qt模型/视图框架一部分。此类用于提供先前由QListBox和QIconView类提供列表和图标视图。...目前我比较常用是和Qt Model一起使用。 体系搭建需要大量基础知识铺垫,并且要不断总结。目前我还是主要写功能方面的应用,所以一般直接上码。...接下来文章会以ListView为切入点,简单说下Qt Model/View与一些窗口部件联系。 本Demo是通过ListView刷新指定文件夹下文件,并可以根据用户选择删除文件。

3.1K50

C++ Qt开发:QFileSystemModel文件管理组件

Qt 是一个跨平台C++图形界面开发库,利用Qt可以快速开发跨平台窗体应用程序,Qt我们可以通过拖拽方式将不同组件放到指定位置,实现图形化开发极大方便了开发效率,本章将重点介绍如何运用QFileSystemModel...QFileSystemModel是Qt框架一个关键类,用于Qt应用程序管理和展示文件系统结构。...该模型提供了一个方便接口,使得开发者可以轻松地应用程序中集成文件和目录树形结构,并通过视图组件(如QTreeView、QListView、QTabView等)展示给用户。...void sort(int column, Qt::SortOrder order) 指定列进行排序。...->setModel(model);}数据模型选中项可通过使用模型内提供各种方法来实现取值,例如使用model->isDir可获取到是否为目录,通过model->filePath则可用于得到文件路径等

28310

《QTreeView+QAbstractItemModel自定义模型》:系列教程之三

那么有哪些model类呢,从下图中我们可以看到 Qt模型层次结构 QStandardItemModel...自定义model (1)原理知识铺垫 我们以实现如下树形显示为例,进行自定义model。...model如何选择 一个项目中开了很多线程,此时QTreeView+QStandardItemModel更新任务信息,更新QTreeView中一行共7列数据,也就是7个单元格数据,居然花了40ms。...自己大概整理了下这2种model不同情况下使用建议: model选择 QStandardItemModel 自定义model 开发难度 简单 稍高 显示大量数据 不建议 建议 显示固定少量数据 建议...不建议 需要更新数据 不建议 建议 对于数据量小且不需要更新场景,我们使用QStandardItemModel来实现比较简单,没有自定义model那么多代码逻辑。

4K10

PyQt5 文本输入框自动补全QLineEdit实现示例

QStandardItemModel提供了一个经典基于项目的方法来处理模型。 QStandardItemModel项目由QStandardItem提供。...QStandardItemModel实现了QAbstractItemModel接口,这意味着该模型可用于支持该接口任何视图(如QListView,QTableView和QTreeView以及您自己自定义视图...当你想要一个列表或树时,你通常会创建一个空QStandardItemModel并使用appendRow()向模型添加项目使用item()来访问项目。...如果您模型表示一个表格,您通常会将表格维度传递给QStandardItemModel构造函数,并使用setItem()将项目放入表格。...您可以使用findItems()模型搜索项目,并通过调用sort()模型进行排序。 调用clear()从模型移除所有项目

3K20

PyQT 拖放事件(一)

许多PyQt窗口部件都支持拖放操作,如QColumnView,QHeaderView, QListView, QTableView 和 QTreeView,我们要做只是打开支持模式使其工作即可。....setDragEnabled(True) #设置为可拖动 .setAcceptDrops(True) #设置为可放下,只有“放下”是从QWidget继承而来 这种方式拖放行为是复制,而不是移动。...如下程序有两个列表控件(QListView),左边列表控件使用默认模式,右边列表控件使用图标模式。项目(QListWidgetItem)可以它们之间拖放复制。 ?...QListWidget, QHBoxLayout,\ QListWidgetItem from PyQt5.QtGui import QIcon from PyQt5.QtCore import Qt...不过,如果需要使其能够处理自定义数据,或者,就必须重新实现一些事件处理程序。

1.8K30

【专业技术】Qt新玩意

编者按:我是一直用Qt,但是仅限于用C++和它Widget写写简单界面,对于这个“新”东西,其实早就不新了,从4.7.x就有了,只不过我项目中没有用,也就一直没有研究它。...使用QML并不需要Qt知识,如果你已经熟悉Qt,那么很多知识都可以直接用于学习和使用QML.当然,使用QML定义UI应用程序还是需要使用Qt实现非UI逻辑....元素时,允许设计者使用绝对几何位置,绑定或描点(从QDeclarativeItem继承而来)定位其外边框,而不是使用布局或指定尺寸.如果适合指定尺寸就将其放置QML文档,让设计者知道如何更好使用这个元素...其他主要不同在于QGraphicWidget用于布局模型,其具有独立UI和逻辑.相反,QML实体通常是具有单一目标的项,不会在所有者履行用户用例,而是QML文件组成等价部件,要避免项定义涉及...UI,例如要进行过度,推荐使用 QDeclarativeItem子类(也可同时使用QGraphicWidget).允许C++轻松为每个C++组件创建一个根项 LayoutItem,向场景中加载独立

2.9K60

Qt TableWidget 控件 及自定义委托

上次和大家分享了TreeWidget简单使用,本次和大家分享下TableWidget简单应用以及项目视图中自定义委托。...设置表头、添加行列、填充单元格内容 Widget上一个TableWidget控件,并不设置布局。之后使用代码设置表头、添加数据等操作。...自定义委托 很久之前和大家分享了Qt Model/View简便类与预定义模型,之后还差自定义模型自定义委托,今天就把自定义委托补上。...这里我想要实现是双击单元格时,通过combox进行选择,原本TableWidget没有这样功能,所以需要通过委托来实现,再所以就需要继承QItemDelegate,之后重新实现一些函数,和Qt 重新封装...后记总结: 这次虽然是简单使用Qt Model/View 自定义委托功能,但是其他复杂功能总体流程也是如此。见微知著,亦或如此吧! 最后: 学不可以已!

2.2K10

图像标注版本3-多标注框+标注标签

多标注框代码重新做了优化,一个是关于正在绘制标注框显示问题,如果标签取消,则不予绘制,如果选择了标签才绘制出来 一、通过qt designer设计一个标签选择自定义Dialog窗口 # -...= QtCore.QCoreApplication.translate Dialog.setWindowTitle(_translate("Dialog", "Dialog")) 二、实现自定义...Dialog相关功能 一个是初始化过程标签列表文件加载 一个是QListView点击事件 一个是Dialog返回值 最后一个是OK按钮事件校验,确保已经选择了标签 from PyQt5...MyLabel进行重写,参见加粗字体部分 引入了一个实时坐标的概念 鼠标移动事件,不断根据鼠标位置进行实时绘制 鼠标释放事件,增加了一个对话框选择项,确认后将相关标注项加入到bboxlist...(bboxlist相对于2.0版本有所调整) 绘制事件,修正了实时标注框单独绘制 from PyQt5.QtWidgets import QWidget, QApplication, QLabel

18220

PyQT模块、类、控件介绍

QtXmlPatterns模块 所包含实现XML和自定义数据模型Xquery与XPath支持。 QtDesigner模块 所包含类允许使用PyQt扩展Qt Designer。...Qt模块 将上面模块类综合到一个单一模块。这样做好处是你不用担心哪个模块包含了哪个特定类;坏处是加载到整个Qt框架,从而增加了应用程序内存占用。...QFrame类 有框架窗口控件基类。它也被用来直接创建没有任何内容简单框架,但是通常要用到QHBox或QVBox,因为它们可以自动布置放到框架窗口控件。...它包含主事件循环,来自窗口系统和其他资源所有事件进行处理和调度;它也对应用程序初始化和结束进行处理,并且提供对话管理;还对绝大多数系统范围和应用程序范围设置进行处理。...可以绘图设备上显示图像,通常放在QLabel或QPushButton类 Qdialog控件 对话框窗口基类 QT Designer控件 控件名称 说明 控件名称 说明 Layouts——布局管理

41731
领券