Qt实现复杂列表

news2024/11/18 13:30:23

Qt实现复杂列表

  • 界面效果
  • layeritemdelegate.h
  • layeritemdelegate.cpp
  • layertablemodel.h
  • layertablemodel.cpp
  • layertableview.h
  • layertableview.cpp
  • mainwindow.h
  • mainwindow.cpp

界面效果

在这里插入图片描述

layeritemdelegate.h

#ifndef LAYERITEMDELEGATE_H
#define LAYERITEMDELEGATE_H

#include <QStyledItemDelegate>
#include <QLineEdit>
#include <QDebug>
#include <QPainter>

class LayerItemDelegate : public QStyledItemDelegate
{
    Q_OBJECT

public:
    LayerItemDelegate(QObject *parent=0);
    ~LayerItemDelegate();


    void paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const;
    QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,
        const QModelIndex &index) const;
    bool editorEvent(QEvent * event,
        QAbstractItemModel * model,
        const QStyleOptionViewItem & option,
        const QModelIndex & index);
    void setEditorData(QWidget *editor, const QModelIndex &index) const;
    void setModelData(QWidget *editor, QAbstractItemModel *model,
        const QModelIndex &index) const;
    void updateEditorGeometry(QWidget *editor,
        const QStyleOptionViewItem &option, const QModelIndex &index) const;

private:
    QPixmap m_gridPixmap;
};

#endif // LAYERITEMDELEGATE_H

layeritemdelegate.cpp

#include "layeritemdelegate.h"

LayerItemDelegate::LayerItemDelegate(QObject *parent)
    : QStyledItemDelegate(parent)
{
    QImage gridImage(200, 200, QImage::Format_RGB32);
    QRgb grey = QColor(204, 204, 204).rgb();
    QRgb white = QColor(255, 255, 255).rgb();
    for (int i = 0; i < 200; i++)
    for (int j = 0; j < 200; j++)
    {
        int tmpX = i % 10;
        int tmpY = j % 10;
        if (tmpX < 5)
        {
            gridImage.setPixel(i, j, tmpY < 5 ? grey : white);
        }
        else
        {
            gridImage.setPixel(i, j, tmpY < 5 ? white : grey);
        }
    }

    m_gridPixmap = QPixmap::fromImage(gridImage);
}

LayerItemDelegate::~LayerItemDelegate()
{

}



void LayerItemDelegate::paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const
{


    if (index.column() == 1) // value column
    {
        if (option.state & QStyle::State_Selected)
            painter->fillRect(option.rect, option.palette.highlight());

        QImage image = qvariant_cast<QImage>(index.data(Qt::DecorationRole));
        //QImage image = index.model()->data(index, Qt::DecorationRole).toString();
        QRect rect = option.rect;
        int x = rect.x() + 10;
        int y = rect.y() + 5;

        QBrush brush;
        //Draw grid background
        brush.setTexture(m_gridPixmap);
        painter->fillRect(x, y, 40, 40, brush);

        //Draw image
        painter->drawImage(x, y, image);

        QRect textRect(rect.x() + 60, rect.y(), rect.width() - 60, rect.height());

        QString layerName = index.model()->data(index, Qt::DisplayRole).toString();
        QTextOption textOption = Qt::AlignLeft | Qt::AlignVCenter;
        painter->drawText(textRect, layerName, textOption);

    }
    else
    {
        QStyledItemDelegate::paint(painter, option, index);
    }
}


bool LayerItemDelegate::editorEvent(QEvent * event,
    QAbstractItemModel * model,
    const QStyleOptionViewItem & option,
    const QModelIndex & index)
{
    return false;
}

QWidget *LayerItemDelegate::createEditor(QWidget *parent,
    const QStyleOptionViewItem &option,
    const QModelIndex &index) const
{
    qDebug() << "createEditor";
    if (index.column() == 1) // value column
    {
        QLineEdit* edit = new QLineEdit(parent);
        edit->setFixedHeight(33);
        edit->setContentsMargins(48, 15, 50, 0);
        return edit;
    }
    else return 0;  // no editor attached
}

void LayerItemDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
    QString value = index.model()->data(index, Qt::EditRole).toString();

    QLineEdit *edit = static_cast<QLineEdit*>(editor);
    edit->setText(value);
    qDebug() << "setEditorData";
}

void LayerItemDelegate::updateEditorGeometry(QWidget *editor,
    const QStyleOptionViewItem &option, const QModelIndex & index ) const
{
    editor->setGeometry(option.rect);
}

void LayerItemDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
    const QModelIndex &index) const
{
    qDebug() << "setModelData";
    QLineEdit *edit = static_cast<QLineEdit*>(editor);
    model->setData(index, edit->text(), Qt::EditRole);
}

layertablemodel.h

#ifndef LAYERLISTMODEL_H
#define LAYERLISTMODEL_H

#include <QAbstractTableModel>
#include <QStringList>
#include <QList>
#include <QPixmap>
#include <QImage>
#include <QIcon>
#include <QDebug>
#include <QItemSelectionModel>

class LayerTableModel : public QAbstractTableModel
{
    Q_OBJECT

public:
    LayerTableModel(QObject *parent = 0);
    ~LayerTableModel();

    int rowCount(const QModelIndex &parent) const;
    int columnCount(const QModelIndex &parent) const;
    QVariant data(const QModelIndex &index, int role) const;
    QVariant headerData(int section,
        Qt::Orientation orientation,
        int role = Qt::DisplayRole) const;
    Qt::ItemFlags flags(const QModelIndex &index) const;

    bool setData(const QModelIndex &index, const QVariant &value, int role);
    void deleteItem(int index);
    void addItem(const QString &layerName,const QImage &thumbnail, bool isShow = true);
    void refreshModel();
//    QModelIndex& selecttedIndex(int row);
    QModelIndex selecttedIndex(int row);
//    QPersistentModelIndex& selecttedIndex(int row);

    void setSelecttedRow(int row);
    int getSelecttedRow() const;


public slots:
    void changeLayerVisibility(const QModelIndex&);

private:
    struct LayerItem
    {
        QString layerName;
        QImage thumbnail;
        float transparence;
        bool isShow;
    };
    QList<LayerItem> layerList;

    int selectedRow;

};

#endif // LAYERLISTMODEL_H

layertablemodel.cpp

#include "layertablemodel.h"
#include"QString"

LayerTableModel::LayerTableModel(QObject *parent)
: QAbstractTableModel(parent)
{
    QImage image("images\\sample.jpg");
    layerList.reserve(3);
    selectedRow = 0;
    for (int i = 0; i < 1; i++)
    {
        addItem(QString(),image,true);
    }
}

LayerTableModel::~LayerTableModel()
{

}

QVariant LayerTableModel::data(const QModelIndex &index, int role) const
{
    if (!index.isValid())
        return QVariant();

    int column = index.column();
    if (column == 0)
    {
        if(role ==  Qt::CheckStateRole)
        {
            return layerList.at(index.row()).isShow ? Qt::Checked : Qt::Unchecked;
        }
        if (role == Qt::SizeHintRole)
        {
            return QSize(20, 50);
        }
    }
    else
    {
        if (role == Qt::EditRole)
        {
            return QVariant(layerList.at(index.row()).layerName);
        }
        if (role == Qt::DisplayRole)
        {
            return QVariant(layerList.at(index.row()).layerName);
        }

        if (role == Qt::DecorationRole)
        {
            if (layerList.at(index.row()).thumbnail.isNull())
            {
                return  layerList.at(index.row()).thumbnail;
            }else
            {
                return  layerList.at(index.row()).thumbnail.scaledToHeight(40);

            }
        }
        if (role == Qt::SizeHintRole)
        {
            return QSize(200, 50);
        }
        if (role == Qt::TextAlignmentRole)
        {
            return int(Qt::AlignVCenter);
        }
    }

    return QVariant();
}

int LayerTableModel::rowCount(const QModelIndex &parent) const
{
    return (parent.isValid() && parent.column() != 0) ? 0 : layerList.size();
}

int LayerTableModel::columnCount(const QModelIndex &parent) const
{
    Q_UNUSED(parent);
    return 2;
}

QVariant LayerTableModel::headerData(int section, Qt::Orientation orientation, int role) const
{
    if (role == Qt::DisplayRole)
        return QString::number(section);
    //if (role == Qt::DecorationRole)
        //return QVariant::fromValue(services);
    return QAbstractItemModel::headerData(section, orientation, role);
}

Qt::ItemFlags LayerTableModel::flags(const QModelIndex &index) const
{

    if (!index.isValid())
        return 0;

    if (index.column() == 0)
        return Qt::ItemIsEnabled | Qt::ItemIsUserCheckable;

    return  Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable;
}

bool LayerTableModel::setData(const QModelIndex &index, const
    QVariant &value, int role)
{
    if (!index.isValid())
    {
        return false;
    }

    if (role == Qt::CheckStateRole && value.type() == QVariant::Bool)
    {
        layerList[index.row()].isShow = value.toBool();
        emit(dataChanged(index, index));
        return true;
    }
    if (role == Qt::EditRole && index.column() == 1)
    {
        layerList[index.row()].layerName = value.toString();
        emit(dataChanged(index, index));
        return true;
    }
    return false;;
}

void LayerTableModel::changeLayerVisibility(const QModelIndex& index)
{
    if (index.isValid()&&index.column() == 0)
    {
        setData(index, !(layerList.at(index.row()).isShow), Qt::CheckStateRole);
    }
}

void LayerTableModel::deleteItem(int index)
{
    QList<LayerItem>::iterator it = layerList.begin();
    layerList.erase(it + index);
}

void LayerTableModel::addItem(const QString &name,const QImage &thumb, bool show)
{
    LayerItem item;
    if (name.size() == 0)
    {
        item.layerName = QString("Layer ") + QString::number(layerList.size());
    }else{
        item.layerName = name;
    }
    item.isShow = show;

    item.thumbnail = thumb;
    layerList.append(item);
    //this->insertRow()
    //emit(dataChanged(index, index));
    qDebug()<<layerList.size();
}

void LayerTableModel::refreshModel()
{
    beginResetModel();
    endResetModel();
    //emit updateCount(this->rowCount(QModelIndex()));
}

//QModelIndex& LayerTableModel::selecttedIndex(int row)
//{
//    return this->createIndex(row, 1);
//}

QModelIndex LayerTableModel::selecttedIndex(int row)
{
    return this->createIndex(row, 1);
}

//QPersistentModelIndex& LayerTableModel::selecttedIndex(int row)
//{
//    static QPersistentModelIndex invalidIndex;  // 返回一个无效的引用,因为不能返回临时对象的引用
//    return this->createIndex(row, 1);
//}




void LayerTableModel::setSelecttedRow(int row)
{
    selectedRow = row;
}

int LayerTableModel::getSelecttedRow() const
{
    return selectedRow;
}

layertableview.h

#ifndef LAYERLISTVIEW_H
#define LAYERLISTVIEW_H

#include <QTableView>
#include <QMouseEvent>
#include <QDebug>
#include <QHeaderView>
#include <QStandardItemModel>
#include <QContextMenuEvent>
#include <QMenu>
#include "layertablemodel.h"
#include "layeritemdelegate.h"

class LayerTableView : public QTableView
{
    Q_OBJECT

public:
    LayerTableView(QWidget *parent = 0);
    ~LayerTableView();
    void setLayerSize(QSize s);

public slots:
    void addNewLayer();
    void deleteLayer();

protected:
    void mouseMoveEvent(QMouseEvent * event);
    void contextMenuEvent(QContextMenuEvent * event);

private:
    LayerItemDelegate *delegate;
    LayerTableModel *model;
    QSize layerSize;

private slots:
    void itemClicked(const QModelIndex&);

};

#endif // LAYERLISTVIEW_H

layertableview.cpp

#include "layertableview.h"
#include <QMessageBox>
LayerTableView::LayerTableView(QWidget *parent)
    : QTableView(parent)
{
    delegate = new LayerItemDelegate();
    model = new LayerTableModel();

    this->setContentsMargins(0, 0, 0, 0);
    this->setModel(model);
    this->setItemDelegate(delegate);

    this->horizontalHeader()->setStretchLastSection(true);
    this->horizontalHeader()->setHighlightSections(false);
    this->setFrameShape(QFrame::NoFrame);
    this->setColumnWidth(0, 30);
    this->setColumnWidth(1, 170);
    this->verticalHeader()->setVisible(false);
    this->horizontalHeader()->setVisible(false);
    this->resizeColumnsToContents();
    this->resizeRowsToContents();
    /*this->setEditTriggers(QAbstractItemView::NoEditTriggers);
    this->setSelectionBehavior(QAbstractItemView::SelectRows);*/
    this->setMouseTracking(true);//important

    //When click on the checkbox it will emit signal twice.Click on the cell emit only once.
    connect(this, SIGNAL(clicked(const QModelIndex&)), this, SLOT(itemClicked(const QModelIndex&)));
}

LayerTableView::~LayerTableView()
{

}

void LayerTableView::mouseMoveEvent(QMouseEvent * event)
{
    Q_UNUSED(event);
}

void LayerTableView::contextMenuEvent(QContextMenuEvent * event)
{

    QMenu *pMenu = new QMenu(this);
    QAction *pAddGroupAct = new QAction(tr("Delete"), pMenu);
    pMenu->addAction(pAddGroupAct);
    pMenu->popup(mapToGlobal(event->pos()));

}

void LayerTableView::addNewLayer()
{
    model->addItem(QString(), QImage(layerSize, QImage::Format_RGB32), true);
    //model->addItem(QString(), QImage("images\\sample.jpg"), true);
    model->refreshModel();
    this->resizeRowsToContents();
}

void LayerTableView::itemClicked(const QModelIndex& index)
{
    if (index.isValid() )
    {
        //When click in column 0.
        if (index.column() == 0)
        {
            // 弹出一条信息框
//            QMessageBox::information(this, "提示", "这是一条消息"); //加this可以有图标
            model->changeLayerVisibility(index);
            QModelIndex tmp = model->selecttedIndex(model->getSelecttedRow());
            this->selectionModel()->select(tmp, QItemSelectionModel::Select);
        }
        //When click in column 1.
        else if (index.column() == 1)
        {
            model->setSelecttedRow(index.row());
        }
    }
}

void LayerTableView::deleteLayer()
{
    model->deleteItem(model->getSelecttedRow());
    model->refreshModel();

    QModelIndex tmp = model->selecttedIndex(0);
    this->selectionModel()->select(tmp, QItemSelectionModel::Select);
}

void LayerTableView::setLayerSize(QSize s)
{
    layerSize = s;
}

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include"layertableview.h"
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    Ui::MainWindow *ui;
    LayerTableView *myLayerTableView;
};
#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include"QHBoxLayout"
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    // 创建 LayerTableView
    myLayerTableView = new LayerTableView();

    // 创建一个水平布局
    QHBoxLayout *layout = new QHBoxLayout;

    // 将 LayerTableView 添加到布局中
    layout->addWidget(myLayerTableView);

    // 创建一个中央部件并设置布局
    QWidget *centralWidget = new QWidget;
    centralWidget->setLayout(layout);

    // 设置中央部件
    setCentralWidget(centralWidget);
}

MainWindow::~MainWindow()
{
    delete ui;
}


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1378705.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【python】搭配Miniconda使用VSCode

现在的spyder总是运行出错&#xff0c;启动不了&#xff0c;尝试使用VSCode。 一、在VSCode中使用Miniconda管理的Python环境&#xff0c;可以按照以下步骤进行&#xff1a; a. 确保Miniconda环境已经安装并且正确配置。 b. 打开VSCode&#xff0c;安装Python扩展。 打开VS…

InternLM第3次课作业

部署 参考github教程&#xff1a;https://github.com/InternLM/tutorial/tree/main/langchain 问题1&#xff1a; windows端口映射过程命令 ssh -i C:\\Users\\breat/.ssh/id_rsa.pub -CNg -L 7860:127.0.0.1:7860 rootssh.intern-ai.org.cn -p 3 4145 中&#xff0c;提示找不…

MetaGPT前期准备与快速上手

大家好&#xff0c;MetaGPT 是基于大型语言模型&#xff08;LLMs&#xff09;的多智能体协作框架&#xff0c;GitHub star数量已经达到31.3k。 接下来我们聊一下快速上手 这里写目录标题 一、环境搭建1.python 环境2. MetaGpt 下载 二、MetaGPT配置1.调用 ChatGPT API 服务2.简…

Unity对应SDK和NDK版本的对照表

官网&#xff1a;Unity - Manual: Android environment setup 本人安装的是2022版本长期支持版本2022.3.15f1c1 安装Java的JDK环境就不在这里展开了&#xff0c;就记录下对Android SDK的设置&#xff0c;要与Unity的版本对应&#xff0c;否则会出现很多莫名奇妙的问题。 打开…

电子学会C/C++编程等级考试2020年12月(三级)真题解析

C/C++编程(1~8级)全部真题・点这里 第1题:完美立方 形如 a^3= b^3 + c^3 + d^3的等式被称为完美立方等式。例如 12^3= 6^3 + 8^3 + 10^3 。 编写一个程序,对任给的正整数 N (N≤100),寻找所有的四元组 (a, b, c, d),使得 a^3= b^3 + c^3 + d^3 ,其中 a,b,c,d均大于 11, …

【Jmeter之get请求传递的值为JSON体实践】

Jmeter之get请求传递的值为JSON体实践 get请求的常见传参方式 1、在URL地址后面拼接&#xff0c;有多个key和value时&#xff0c;用&链接 2、在Parameters里面加上key和value 第一次遇到value的值不是字符串也不是整型&#xff0c;我尝试把json放到value里面&#xff0…

java多线程面试(二)

1.说一下你对java内存模型JVM的理解 java内存模型是一种抽象的模型&#xff0c;被定义出来屏蔽各种硬件和操作系统的访问差异。 JMM定义了线程和主内存之间的抽象关系&#xff1a;线程之间的共享变量存储在主内存 &#xff08;Main Memory&#xff09;中&#xff0c;每个线程…

SQL语句详解二-DDL(数据定义语言)

文章目录 操作数据库创建&#xff1a;Create查询&#xff1a;Retrieve修改&#xff1a;Update删除&#xff1a;Delete使用数据库 操作表常见的几种数据类型创建&#xff1a;Create复制表 查询&#xff1a;Retrieve修改&#xff1a;Update删除&#xff1a;Delete 操作数据库 创…

Spring Cloud配置中心

微服务意味着要将单体应用中的业务拆分成一个个子服务 , 每个服务的粒度相对较小 ,因此系统中会出现大量的服务。 由于每个服务都需要必要的配置信息才能运行 , 所以一套集中式的 , 动态的配置管理设施是必不可少的。 Spring Cloud 提供了 ConfigServer 来解决这个问题 . Sp…

客户端请求服务器的步骤

当我们在浏览器地址栏输入’http://www.xxx.com/api/xxx"时&#xff0c;客户端是如何找到服务器并发送请求的&#xff1f; 1.先找到服务器 a.检测浏览器缓存有没有缓存该域名对应的IP地址&#xff0c;有则通过IP地址取找服务器。 b.检测本地的hosts文件&#xff0c;是否有…

ROS2——launcher

在ROS2中&#xff0c;launcher 文件是通过Python构建的&#xff0c;它们的功能是声明用哪些选项或参数来执行哪些程序&#xff0c;可以通过 launcher 文件快速同时启动多个节点。一个 launcher 文件内可以引用另一个 launcher 文件。 使用 launcher 文件 ros2 launch 可以代替…

STM32 SPI通信协议3——读取MAX6675温度传感器

在上两章中&#xff0c;我们已经配置了相应的GPIO和SPI功能。这里说一下MAX6675如何读取温度。 从MAX6675手册中我们可以看到&#xff0c;当0的时候SCK启动&#xff0c;数据线开始发送信息&#xff0c;此时可以读取数据&#xff0c;当数据读完后&#xff0c;再拉高电平停止发送…

VMware Workstation17安装教程及安装Ubuntu22.04系统

编程如画&#xff0c;我是panda&#xff01; 前言 VMware Workstation Pro 是一款高级虚拟化软件&#xff0c;使用户能够在单一计算机上同时运行多个操作系统&#xff0c;如Windows、Linux和macOS&#xff0c;而无需重新启动。具备虚拟机快照、高级网络配置、克隆和复制功能&a…

Redis-浅谈redis.conf配置文件

Redis.conf Redis.conf是Redis的配置文件&#xff0c;它包含了一系列用于配置Redis服务器行为和功能的选项。 以下是Redis.conf中常见的一些选项配置&#xff1a; bind: 指定Redis服务器监听的IP地址&#xff0c;默认为127.0.0.1&#xff0c;表示只能本地访问&#xff0c;可以…

大数据毕业设计:房屋数据分析可视化系统 预测算法 可视化 商品房数据 Flask框架(源码+讲解视频)✅

毕业设计&#xff1a;2023-2024年计算机专业毕业设计选题汇总&#xff08;建议收藏&#xff09; 毕业设计&#xff1a;2023-2024年最新最全计算机专业毕设选题推荐汇总 &#x1f345;感兴趣的可以先收藏起来&#xff0c;点赞、关注不迷路&#xff0c;大家在毕设选题&#xff…

网卡高级设置-提高网络环境

网卡高级设置&#xff0c;提高网络质量排除一些连接问题 一、有线网卡 1、关闭IPv6&#xff1b; 可以关闭协议版本6&#xff0c;因为它会引起一些网络连接问题&#xff0c;而且现在几乎用不到IP6。 2、关闭节约电源模式&#xff1b; 右击计算机->设备->设备管理器-&…

Unity游戏开发面试知识点全解读

Unity游戏开发面试知识点全解读 在数字化世界中&#xff0c;Unity游戏开发不仅是一种艺术形式和商业活动&#xff0c;而且已成为推动整个数字娱乐产业创新和进步的重要力量。Unity以其易用性、高效性和灵活性&#xff0c;赢得了全球开发者的青睐&#xff0c;从独立开发者到大型…

MySQL题目示例

文章目录 1.题目示例 1.题目示例 09&#xff09;查询学过「张三」老师授课的同学的信息 SELECT s.*, c.cname, t.tname, sc.score FROM t_mysql_teacher t, t_mysql_course c, t_mysql_student s, t_mysql_score sc WHERE t.tid c.tid AND c.cid sc.cid AND sc.sid s.sid …

07- OpenCV:模糊图像

目录 一、模糊原理 二、模糊的相关处理方法&#xff1a; 1、均值滤波&#xff08;归一化盒子滤波&#xff09; 2、高斯滤波&#xff08;正态分布的形状&#xff09; 3、中值模糊 4、双边模糊算法&#xff08;美容软件&#xff09; 5、相关代码&#xff1a; 6、几种模糊算法的比…

【问题记录】数据处理部分正常部分异常

一&#xff0c;问题现象 正常处理效果为压缩到-12db&#xff0c;一部分压缩效果正确&#xff0c;一部分数据处理效果不正确。准确来说&#xff0c;只有1/4的数据处理正确。 二&#xff0c;问题原因 传入process的size不正确&#xff0c;导致读出来4096个字节&#xff0c;但…