【嵌入式——QT】QStyledItemDelegate用法详解

这篇具有很好参考价值的文章主要介绍了【嵌入式——QT】QStyledItemDelegate用法详解。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

QStyledItemDelegate是所有Qt item视图的默认委托,在创建它们时就会被安装在它们上面。
QStyledItemDelegate类是模型/视图类之一,是Qt模型/视图框架的一部分。委托允许项目的显示和编辑独立于模型和视图进行开发。
模型中数据项的数据被赋值为ItemDataRole;每个物品可以为每个角色存储一个QVariant。QStyledItemDelegate实现了用户所期望的最常见数据类型的显示和编辑,包括布尔值、整数和字符串。
根据数据在模型中的角色不同,数据将以不同的方式绘制。
继承QStyledItemDelegate需要重写的四个方法:

//返回用于编辑由索引指定的项的小部件
QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const override;
//从模型索引指定的数据模型项设置要由编辑器显示和编辑的数据,默认实现将数据存储在editor小部件的user属性中
void setEditorData(QWidget* editor, const QModelIndex& index) const override;
//从editor小部件获取数据,并将其存储在项目索引处的指定模型中,默认实现从editor小部件的user属性获取要存储在数据模型中的值
void setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const override;
//更新由索引指定的项的编辑器
void updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index) const override;

首先要继承QStyledItemDelegate,并实现上面提到的四个方法。
代码示例:
CustomStyledItem.h

#include <QObject>
#include <QStyledItemDelegate>
enum COLUMN_HEAD_INDEX {
    CheckBox = 0,
    Id = 1,
    Format=2,
    Type=3,
    SendMode = 4,
    Length=5,
    Data=6,
    SendTimes=7,
    Interval=8,
    Count = 9,
    CANType = 10,
    BRS = 11
};
class CustomStyledItem : public QStyledItemDelegate
{
public:
    explicit CustomStyledItem(QObject* parent, int channel);
    CustomStyledItem();

    QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const override;
    void setEditorData(QWidget* editor, const QModelIndex& index) const override;
    void setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const override;
    void updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index) const override;

private :
    int channel ;
};

CustomStyledItem.cpp

#include "CustomStyledItem.h"
#include <QCheckBox>
#include <QComboBox>
#include <QDebug>
#include "DevCan.h"

CustomStyledItem::CustomStyledItem(QObject* parent, int channel) : QStyledItemDelegate(parent), channel(channel)
{
}

CustomStyledItem::CustomStyledItem()
{
}

QWidget* CustomStyledItem::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const
{
    const QString style = R"(QCheckBox {padding-left: 4px; background-color: white; })";
    QCheckBox* cbBox;
    QComboBox* cb;
    switch(index.column()) {
        case CheckBox:
            cbBox = new QCheckBox(parent);
            cbBox->setStyleSheet(style);
            return cbBox;
            break;
        case Id:
            break;
        case Format:
            cb = new QComboBox(parent);
            if(((DevCan::instance().getDevType() == VCI_USBCANFD_II) ||
                (DevCan::instance().getDevType() == VCI_USBCANFD_I)) &&
               (DevCan::instance().getChannelType(channel) == CANFD_CH)) {
                cb->addItem(tr("Data Frame"), 0);
            } else {
                cb->addItem(tr("Data Frame"), 0);
                cb->addItem(tr("Remote Frame"), 1);
            }
            return cb;
            break;
        case Type:
            cb = new QComboBox(parent);
            cb->addItem(tr("Standard Frame"), 0);
            cb->addItem(tr("Extend Frame"), 1);
            return cb;
            break;
        case SendMode:
            cb = new QComboBox(parent);
            cb->addItem(tr("Normal Send"), 0);
            cb->addItem(tr("Single Send"), 1);
            cb->addItem(tr("Send & Receive"), 2);
            cb->addItem(tr("Single Send&Rec"), 3);
            return cb;
            break;
        case Length:
            break;
        case Data:
            break;
        case SendTimes:
            break;
        case Interval:
            break;
        case Count:
            break;
        case CANType:
            break;
        case BRS:
            break;
        default:
            break;
    }
    return NULL;
}

void CustomStyledItem::setEditorData(QWidget* editor, const QModelIndex& index) const
{
    QCheckBox* cbWidget;
    QComboBox* cb;
    int formatIndex;
    switch(index.column()) {
        case CheckBox:
            cbWidget = dynamic_cast<QCheckBox*>(editor);
            cbWidget->setChecked(index.data(Qt::DisplayRole).toString() == "Yes");
            break;
        case Id:
            break;
        case Format:
            cb = dynamic_cast<QComboBox*>(editor);
            cb->setCurrentIndex(index.data(Qt::DisplayRole).toBool()?0:1);
            break;
        case Type:
            cb = dynamic_cast<QComboBox*>(editor);
            cb->setCurrentIndex(index.data(Qt::DisplayRole).toBool()?0:1);
            break;
        case SendMode:
            cb = dynamic_cast<QComboBox*>(editor);
            cb->setCurrentIndex(index.data(Qt::DisplayRole).toBool()?0:1);
            break;
        case Length:
            break;
        case Data:
            break;
        case SendTimes:
            break;
        case Interval:
            break;
        case Count:
            break;
        case CANType:
            break;
        case BRS:
            break;
        default:
            break;
    }
}

void CustomStyledItem::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const
{
    QComboBox* cb;
    bool state;
    switch(index.column()) {
        case CheckBox:
            state = dynamic_cast<QCheckBox*>(editor)->isChecked();
            //阻止模型发出信号
            model->blockSignals(true);
            model->setData(index, state ? Qt::Checked : Qt::Unchecked, Qt::CheckStateRole);
            //模型可以发出信号
            model->blockSignals(false);
            model->setData(index, state, Qt::UserRole);
            break;
        case Id:
            break;
        case Format:
            cb = dynamic_cast<QComboBox*>(editor);
            model->setData(index, cb->currentText(), Qt::EditRole);
            break;
        case Type:
            cb = dynamic_cast<QComboBox*>(editor);
            model->setData(index, cb->currentText(), Qt::EditRole);
            break;
        case SendMode:
            cb = dynamic_cast<QComboBox*>(editor);
            model->setData(index, cb->currentText(), Qt::EditRole);
            break;
        case Length:
            break;
        case Data:
            break;
        case SendTimes:
            break;
        case Interval:
            break;
        case Count:
            break;
        case CANType:
            break;
        case BRS:
            break;
        default:
            break;
    }
}

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

那么我们如何使用这个类呢,废话不多说,直接上代码,相信大家一看就全都明白了。
首先呢,我们将表格进行初始化,这是在你的项目代码中完成的,如MainWindow.cpp


void BottomTableView::initUI()
{
	//这个就是关键方法了,这行代码的意思是,将第1列添加一个自定义的小部件,就是我们上面创建的复选框
    ui->tableViewBottom->setItemDelegateForColumn(0, new CustomStyledItem(ui->tableViewBottom, channel));
    //第3列
    ui->tableViewBottom->setItemDelegateForColumn(2, new CustomStyledItem(ui->tableViewBottom, channel));
    //第4列
    ui->tableViewBottom->setItemDelegateForColumn(3, new CustomStyledItem(ui->tableViewBottom, channel));
    //第5列
    ui->tableViewBottom->setItemDelegateForColumn(4, new CustomStyledItem(ui->tableViewBottom, channel));
    modelBottom = new QStandardItemModel(ui->tableViewBottom);
    if(((DevCan::instance().getDevType() == VCI_USBCANFD_II) ||
        (DevCan::instance().getDevType() == VCI_USBCANFD_I)) &&
       (DevCan::instance().getChannelType(channel) == CANFD_CH)) {
        modelBottom->setHorizontalHeaderLabels(QStringList()<<tr(" ")<<tr("Id")<<tr("Format")<<tr("Type")<<tr("SendMode")
                                               <<tr("Length")<<tr("Data(HEX)")<<tr("Send Times")<<tr("Interval(ms)")
                                               <<tr("Count")<<tr("CANType")<<tr("BRS"));
    } else {
        modelBottom->setHorizontalHeaderLabels(QStringList()<<tr(" ")<<tr("Id")<<tr("Format")<<tr("Type")
                                               <<tr("SendMode")<<tr("Length")<<tr("Data(HEX)")<<tr("Send Times")
                                               <<tr("Interval(ms)")<<tr("Count"));
    }
    ui->tableViewBottom->setModel(modelBottom);
    // //隐藏垂直表头
    ui->tableViewBottom->verticalHeader()->setVisible(false);
    //设置表格的网格线风格为自定义虚线风格
    ui->tableViewBottom->setGridStyle(Qt::CustomDashLine);
    //开启交替行颜色
    // ui->tableViewBottom->setAlternatingRowColors(true);
    //设置选择模式为扩展选择,这意味着用户可以选择多个连续或不连续的行和列
    // ui->tableViewBottom->setSelectionMode(QAbstractItemView::ExtendedSelection);
    //设置选择行为为选择行,这意味着当用户点击表格的任何地方时,整行都会被选中
    // ui->tableViewBottom->setSelectionBehavior(QAbstractItemView::SelectRows);
    //设置编辑触发器为无,这意味着表格不应在用户进行任何操作时进入编辑模式
    // ui->tableViewBottom->setEditTriggers(QAbstractItemView::NoEditTriggers);
    //设置表格的框架形状为矩形框
    // ui->tableViewBottom->setFrameShape(QFrame::Box);
    //设置表格框架的阴影为下沉样式,这通常会使表格看起来更立体
    // ui->tableViewBottom->setFrameShadow(QFrame::Sunken);
    //设置列宽
    ui->tableViewBottom->horizontalHeader()->resizeSection(0, 50);
    ui->tableViewBottom->horizontalHeader()->resizeSection(1, 100);
    ui->tableViewBottom->horizontalHeader()->resizeSection(2, 150);
    ui->tableViewBottom->horizontalHeader()->resizeSection(3, 150);
    ui->tableViewBottom->horizontalHeader()->resizeSection(4, 200);
    ui->tableViewBottom->horizontalHeader()->resizeSection(5, 80);
    ui->tableViewBottom->horizontalHeader()->resizeSection(6, 150);
    ui->tableViewBottom->horizontalHeader()->resizeSection(7, 150);
    ui->tableViewBottom->horizontalHeader()->resizeSection(8, 150);
    ui->tableViewBottom->horizontalHeader()->resizeSection(9, 150);
    if(((DevCan::instance().getDevType() == VCI_USBCANFD_II) ||
        (DevCan::instance().getDevType() == VCI_USBCANFD_I)) &&
       (DevCan::instance().getChannelType(channel) == CANFD_CH)) {
        ui->tableViewBottom->horizontalHeader()->resizeSection(10, 100);
        ui->tableViewBottom->horizontalHeader()->resizeSection(11, 100);
    }
    //将表格的水平表头的最后一个section设置为可拉伸
    ui->tableViewBottom->horizontalHeader()->setStretchLastSection(true);
    //取消水平表头的高亮
    ui->tableViewBottom->horizontalHeader()->setHighlightSections(false);
    //水平表头对其方式
    ui->tableViewBottom->horizontalHeader()->setDefaultAlignment(Qt::AlignVCenter);
    //隐藏垂直表头
    // ui->tableViewBottom->verticalHeader()->setVisible(false);
    //垂直表头对其方式居中对齐
    ui->tableViewBottom->verticalHeader()->setDefaultAlignment(Qt::AlignCenter);
    //设置行高
    ui->tableViewBottom->verticalHeader()->setDefaultSectionSize(30);
    //垂直表头的大小调整为适应其内容
    ui->tableViewBottom->verticalHeader()->resizeSections(QHeaderView::ResizeToContents);
}

表格初始化好了,接下来就是像表格上添加数据了,请看下面代码
这里,我用到了QSettings 来进行数据的存储,并取用,这部分知识在之后的文章中会再次提到的。


void BottomTableView::loadSendMsg()
{
    //先清空
    modelBottom->removeRows(0, modelBottom->rowCount());
    int size = 0;
    int colNum ;
    QString applicationName = QString("%1_%2").arg("BASESEND", QString::number(channel));
    QSettings settings(QSettings::NativeFormat, QSettings::UserScope, "Tegcan", applicationName);
    if(((DevCan::instance().getDevType() == VCI_USBCANFD_II) ||
        (DevCan::instance().getDevType() == VCI_USBCANFD_I)) &&
       (DevCan::instance().getChannelType(channel) == CANFD_CH)) {
        size = settings.beginReadArray("sendMsgsFD");
        colNum = 12;
    } else {
        size = settings.beginReadArray("sendMsgs");
        colNum = 10;
    }
    if(size == 0) {
        return;
    }
    QString idStr="";
    QString externFlag = "";
    QString remoteFlag = "";
    QString sendModeStr = "";
    QString canTypeStr = "";
    QString brsStr = "";
    for(int row=0; row<size; row++) {
        settings.setArrayIndex(row);
        for(int col = 0; col< colNum; col++) {
        	//这就相当于是创建了一个单元,然后向单元中填充数据
            QStandardItem* newItem=new QStandardItem;
            int ID = settings.value("ID").toInt();
            int sendModeI = settings.value("SendMode").toInt();
            if(settings.value("ExternFlag").toInt() == 0) {
                externFlag = tr("Standard Frame");
                idStr = settings.value("ID").toString().sprintf("0x%03X", ID);
            } else {
                externFlag = tr("Extend Frame");
                idStr = settings.value("ID").toString().sprintf("0x%08X", ID);
            }
            switch(col) {
                case CheckBox:
                    //CheckBox
                    //Qt::CheckStateRole 这代码复选框角色
                    newItem->setData(Qt::Unchecked, Qt::CheckStateRole);
                    break;
                case Id:
                    //ID
                    newItem->setData(idStr, Qt::DisplayRole);
                    newItem->setEditable(false);
                    break;
                case Format:
                    //Format
                    if(settings.value("RemoteFlag").toInt() == 0) {
                        remoteFlag = tr("Data Frame");
                    } else {
                        remoteFlag = tr("Remote Frame");
                    }
                    if(((DevCan::instance().getDevType() == VCI_USBCANFD_II) ||
                        (DevCan::instance().getDevType() == VCI_USBCANFD_I)) &&
                       (DevCan::instance().getChannelType(channel) == CANFD_CH)) {
                        newItem->setData(remoteFlag, Qt::DisplayRole);
                    } else {
                        newItem->setData(remoteFlag, Qt::EditRole);
                    }
                    break;
                case Type:
                    //Type
                    //Qt::EditRole 这代表可编辑角色
                    newItem->setData(externFlag, Qt::EditRole);
                    break;
                case SendMode:
                    //SendMode
                    switch(sendModeI) {
                        case 0:
                            sendModeStr=tr("Normal Send");
                            break;
                        case 1:
                            sendModeStr=tr("Single Send");
                            break;
                        case 2:
                            sendModeStr=tr("Send & Receive");
                            break;
                        case 3:
                            sendModeStr=tr("Single Send&Rec");
                            break;
                        default:
                            break;
                    }
                    newItem->setData(sendModeStr, Qt::EditRole);
                    break;
                case Length:
                    //Length
                    //Qt::DisplayRole 这个表示该列数据仅是展示,不可修改
                    newItem->setData(settings.value("DataLen").toString(), Qt::DisplayRole);
                    newItem->setEditable(false);
                    break;
                case Data:
                    //Data(HEX)
                    newItem->setData(settings.value("Data").toString(), Qt::DisplayRole);
                    break;
                case SendTimes:
                    //Send Times
                    newItem->setData(settings.value("Times").toString(), Qt::DisplayRole);
                    break;
                case Interval:
                    //Interval(ms)
                    newItem->setData(settings.value("Interval").toString(), Qt::DisplayRole);
                    break;
                case Count:
                    //Count
                    newItem->setData(0, Qt::DisplayRole);
                    newItem->setEditable(false);
                    break;
                case CANType:
                    //CANType
                    if(settings.value("CANType").toInt() == 0) {
                        canTypeStr = "CAN";
                    } else {
                        canTypeStr = "CANFD";
                    }
                    newItem->setText(canTypeStr);
                    newItem->setData(canTypeStr, Qt::DisplayRole);
                    newItem->setEditable(false);
                    break;
                case BRS:
                    //BRS
                    if(settings.value("BRS").toInt() == 0) {
                        brsStr = "Disable BRS";
                    } else {
                        brsStr = "Enable BRS";
                    }
                    // newItem->setText(brsStr);
                    newItem->setData(brsStr, Qt::DisplayRole);
                    newItem->setEditable(false);
                    break;
                default:
                    break;
            }
            modelBottom->setItem(row, col, newItem);
        }
        idStr.clear();
        externFlag.clear();
        remoteFlag.clear();
        sendModeStr.clear();
        canTypeStr.clear();
        brsStr.clear();
    }
    settings.endArray();
}

我们这里用到了复选框,我的项目中的主要是判断哪一条数据是被选中了的,所以我需要判断一下复选框的状态,被选中的数据会被发送到硬件设备上,代码如下:


void BottomTableView::sendMessage(int flag)
{
    if(flag ==0) {
        UlGlobalSet::instance().channel[channel].nStrategicType = TIMING;
    } else if(flag ==1) {
        UlGlobalSet::instance().channel[channel].nStrategicType = RECYCLE;
    } else {
        UlGlobalSet::instance().channel[channel].nStrategicType = ORDER;
    }
    QModelIndex index = ui->tableViewBottom->currentIndex();
    int rows = index.model()->rowCount();
    taskQueue tObjQ;
    for(int i=0; i<rows; i++) {
        QStandardItem* qs = modelBottom->item(i, 0);
        QStandardItemModel* model = qs->model();
        QModelIndex checkBoxIndex = model->index(i, CheckBox);
        int isCheck = model->data(checkBoxIndex, Qt::CheckStateRole).toInt();
        qDebug()<<"isCheck==="<<isCheck;
        if(isCheck == Qt::Checked) {
            taskObj tObj;
            if(((DevCan::instance().getDevType() == VCI_USBCANFD_II) ||
                (DevCan::instance().getDevType() == VCI_USBCANFD_I)) &&
               (DevCan::instance().getChannelType(channel) == CANFD_CH)) {
                if(analyseFDObj(tObj)) {
                    tObjQ.append(tObj);
                }
            } else {
                if(analyseObj(tObj, i)) {
                    tObjQ.append(tObj);
                }
            }
        }
    }
}

代码写完之后就可以双击在你所设置的单元格中直接编辑了,展示一下页面吧!!!
初始页面
【嵌入式——QT】QStyledItemDelegate用法详解,qt,iot,嵌入式硬件,物联网
下拉选择修改
【嵌入式——QT】QStyledItemDelegate用法详解,qt,iot,嵌入式硬件,物联网
文本框编辑
【嵌入式——QT】QStyledItemDelegate用法详解,qt,iot,嵌入式硬件,物联网文章来源地址https://www.toymoban.com/news/detail-816442.html

到了这里,关于【嵌入式——QT】QStyledItemDelegate用法详解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【嵌入式——QT】容器类

    Qt提供了基于模板的容器类,这些容器类可以用于存储指定类型的数据项,Qt的容器类比标准模板库(STL)中的容器类更轻巧、安全和易于使用。它们还是线程安全的,它们作为只读容器时可被多个线程访问。 容器类是基于模板的类,如常用的容器类QList,T是一个具体的类型,可

    2024年02月22日
    浏览(49)
  • 【嵌入式Qt开发入门】初识Qt——Linux下安装Qt

            Qt 是一个跨平台的 C++开发库。主要用来开发图形用户界面(Graphical User Interface,简 称 GUI)程序。         Qt 虽然经常被当做一个 GUI 库,用来开发图形界面应用程序,但这并不是 Qt 的全部; Qt 除了可以绘制漂亮的界面(包括控件、布局、交互),还包含很多

    2024年02月16日
    浏览(60)
  • 嵌入式 QT 界面布局管理

    目录 1、实例程序功能 2、界面组件布局 2.1 界面组件的层次关系 2.2 布局管理 2.3 伙伴关系和Tab顺序       创建一个 Widget Application 项目 samp2_2, 在创建窗体时选择基类 QDialog ,生成的类命名为 QWDialog ,并选择生成窗体。     如 此 新建 的项 目 samp2_2 有一 个界 面文 件 qwdi

    2024年02月04日
    浏览(56)
  • 嵌入式:QT Day4

    源码: widget.h widget.cpp main.cpp

    2024年02月14日
    浏览(41)
  • 嵌入式:QT Day2

    源码: widget.h second.h widget.cpp second.cpp main.cpp    

    2024年02月15日
    浏览(45)
  • 嵌入式:QT Day1

    源码: widge.h  widge.cpp  main.cpp

    2024年02月15日
    浏览(48)
  • 【嵌入式Qt开发入门】如何使用Qt进行绘图——QPainter 绘图

            绘图与图表在嵌入式里有的比较多,尤其是图表,我们常在股票里看到的“图表折线/曲线 图/饼状图等”都可以用 Qt 的图表来实现。绘图和图表的内容本章主要介绍绘图和图表的基本操作,以简单的例子呈现绘图与图表的用法,目的就是快速入门绘图与图表,关

    2024年02月12日
    浏览(48)
  • Qt固件映像 Raspberry Pi 嵌入式C++(Qt)编程

    在我们的游戏中,我们有一个桨、一个球和三十块砖。 计时器用于创建游戏周期。 我们不处理角度,我们只是改变方向:上、下、左、右。 Qt5 库是为创建计算机应用程序而开发的。尽管如此,它也可以用来创建游戏。开发计算机游戏是了解有关 Qt5 的更多信息的好方法。

    2024年01月19日
    浏览(43)
  • 嵌入式 QT纯代码设计UI

        目录 1.1 实例功能 1.2 界面创建 1.3 界面组件的创建与布局 1.4 信号与槽的关联 UI 的可视化设计是对用户而言的,其实底层都是 C++ 的代码实现,只是 Qt 巧妙地进行了处理,让用户 省去了很多繁琐的界面设计工作。   由于界面设计的底层其实都是由 C++ 语言实现的,底层

    2024年03月09日
    浏览(55)
  • 嵌入式开发板qt gdb调试

    1) 启动 gdbserver ssh 或者 telnet 登陆扬创平板 192.168.0.253, 进入命令行执行如下: chmod 777 /home/HelloWorld (2) 打 开 QTcreator-Debug-StartDebugging-Attach to Running Debug Server 进行如下设置,设置监听端口10000. 点击上图中的按钮,由于按钮中的函数设置了断点,则跳到断点,界面如下

    2024年02月04日
    浏览(95)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包