找到具有可变字段的正确qt数据模型

时间:2018-07-01 18:30:16

标签: c++ qt

我正在寻找一个数据模型。 Qt提供了很多选择,所以我想向您提出建议。

这是我的数据模型结构的简化示例:

  • 它具有两个字段:字段1和字段2。

  • Field1可以是“ none”,“ option”或“ number”

  • 如果field1为“ none”,则field2应为空且不包含任何选项。

  • 如果field1是“ option”,那么field2应该给我一个“ a”或“ b”的选项

  • 如果field1是“数字”,那么field2应该让我选择输入1到100之间的任何数字。

我希望在表格上有一个表格,其中包含此数据的视图,并带有组合框或旋转框以选择数据。除了指定的其他数据,应该不能输入。

能否请您指出正确的方向,并提供一个示例,说明如何在Qt中以最简单的方式实现此目标。

我希望能够将这些数据也存储到文件中,我可能会使用json。

1 个答案:

答案 0 :(得分:0)

假设您了解Qt的模型/视图系统,并且知道应该使用 View 可视化数据模型,那么进一步实现的就是委托。 strong>,它可以为每个字段提供除文本输入之外的其他界面。

根据此tutorial,您应该执行以下操作:

子类化QStyledItemDelegate,创建自己的委托类,例如MyDelegate


class MyDelegate : public QStyledItemDelegate
{
    Q_OBJECT
public:
    enum  FIELDS
    {

        COL_FIELD1,
    };

    explicit MyDelegate(QObject *parent = nullptr);

    QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,
                          const QModelIndex &index) const Q_DECL_OVERRIDE;

    void setEditorData(QWidget *editor, const QModelIndex &index) const Q_DECL_OVERRIDE;
    void setModelData(QWidget *editor, QAbstractItemModel *model,
                      const QModelIndex &index) const Q_DECL_OVERRIDE;

    void updateEditorGeometry(QWidget *editor,
        const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE;

};

实现这些功能

  • createEditor ,定义供用户执行编辑任务的窗口小部件
  • setEditorData ,将数据从DataModel转换为小部件
  • setModelData ,将数据从Widget转换为DataModel
  • updateEditorGeometry ,定义在该字段中查找的小部件。

在以下代码上,我试图找出您需要提供field1选项的情况。

#include "mydelegate.h"

MyDelegate::MyDelegate(QObject *parent) : QStyledItemDelegate(parent)
{

}


QWidget* MyDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    QComboBox* __comboBox = new QComboBox(parent);

    if(index.column()==COL_FIELD1)
    {
        __comboBox->addItem("none");
        __comboBox->addItem("option");
        __comboBox->addItem("number");
    }
    else
    {
        //! according to your need...
    }

    return __comboBox;
}

void MyDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
    QComboBox* __comboBox = qobject_cast<QComboBox*>(editor);

    if(index.column()==COL_FIELD1)
    {
         __comboBox->setCurrentText(index.model()->data(index).toString());
    }
}

void MyDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
    QComboBox* __comboBox = qobject_cast<QComboBox*>(editor);

    model->setData(index,QVariant::fromValue(__comboBox->currentText()));
}

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

实例化MyDelegate,附加到您的视图

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    //! prepare a demo model
    QStringListModel *model = new QStringListModel();
       QStringList list;
       list << "a" << "b" << "c";
       model->setStringList(list);

    //! attach a MyDelegate for Row1
    ui->tableView->setModel(model);
    ui->tableView->setItemDelegateForRow(0,new MyDelegate(this));
}

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

降神效果如下:

enter image description here

只需尝试更改MyDelegate的实现内容即可获得所需的效果(例如spinBox或Field2的其他选项),尽情享受吧!