Найти правильную модель данных QT с переменными полями - PullRequest
0 голосов
/ 01 июля 2018

Я ищу модель данных. Qt предлагает много вариантов, поэтому я хотел бы получить ваш совет.

Вот упрощенный пример структуры моей модели данных:

  • Имеет два поля: поле 1 и поле 2.

  • Поле1 может быть «none», «option» или «number»

  • Если поле field1 равно none, поле field2 должно быть пустым и не содержать параметров.

  • Если field1 это «опция», field2 должна дать мне опцию «a» или «b»

  • Если field1 - «число», field2 должно дать мне возможность ввести любое число от 1 до 100.

Я хотел бы иметь табличное представление этих данных в форме, со списком или спинбоксами для выбора данных. Не должно быть возможности вводить какие-либо другие данные, кроме указанных.

Не могли бы вы указать мне правильное направление и, возможно, привести пример того, как реализовать это наиболее простым способом в Qt.

Я хочу также сохранить эти данные в файле, для которого я, вероятно, буду использовать json.

1 Ответ

0 голосов
/ 02 июля 2018

Предполагается, что вы знакомы с системой моделей / представлений Qt и знаете, что вам следует использовать Просмотр для визуализации вашей модели данных. Тогда вы собираетесь реализовать больше - делегат, который может предложить дополнительный интерфейс, кроме ввода текста для каждого поля.

Согласно этому учебнику , вы должны сделать следующее:

Создание подкласса 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 , преобразование данных из виджета в DataModel
  • updateEditorGeometry , определить виджет, глядя в поле.

В следующих кодах я попытался выяснить, нужно ли вам предлагать варианты поля 1.

#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), получайте удовольствие!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...