选择新的委托后如何更新QTableWidgetItems?

时间:2018-07-25 17:10:23

标签: c++ qt qt5 c++14 qtablewidgetitem

我创建了一个QTableWidget,它根据一个按钮更改了委托。我已经能够使用QTableWidget设置不同的委托,但是更改委托似乎并不会自动更新QTableWidgetItems。当我通过实际UI进入用户对QTableWidget项的编辑时,该项将正确更新为正确的委托。

这是我用来更新委托的代码示例:

//here is the item delegate I used
#include <QItemDelegate>
#include <QSpinBox>
#include <limits>

class IntDelegate : public QItemDelegate {
    int m_min;
    int m_max;
public:
    explicit IntDelegate(int min = std::numeric_limits<int>::min(),
                         int max = std::numeric_limits<int>::max(),
                         QObject *parent = nullptr) : QItemDelegate(
            parent), m_min(min), m_max(max) {
    }

    QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,
                          const QModelIndex &index) const override {
        auto spinbox = new QSpinBox(parent);
        spinbox->setMinimum(m_min);
        spinbox->setMaximum(m_max);
        return spinbox;
    }

    void setEditorData(QWidget *editor,
                       const QModelIndex &index) const override {
        int value = index.model()->data(index, Qt::EditRole).toInt();
        auto *spinBox = static_cast<QSpinBox *>(editor);
        spinBox->setValue(value);
    }

    void setModelData(QWidget *editor, QAbstractItemModel *model,
                      const QModelIndex &index) const override {
        auto *spinBox = static_cast<QSpinBox *>(editor);
        spinBox->interpretText();
        int value = spinBox->value();

        model->setData(index, value, Qt::EditRole);
    }

    void updateEditorGeometry(QWidget *editor,
                              const QStyleOptionViewItem &option,
                              const QModelIndex &index) const override {
        editor->setGeometry(option.rect);
    }
};
#include <QItemDelegate>
#include <QDoubleSpinBox>
#include <limits>

class DoubleDelegate : public QItemDelegate {
double m_min;
double m_max;
public:
explicit DoubleDelegate(double min = -std::numeric_limits<double>::max(),
                        double max = std::numeric_limits<double>::max(),
                        QObject *parent = nullptr) : QItemDelegate(
        parent), m_min(min), m_max(max) {
}

QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,
                      const QModelIndex &index) const override {
    auto spinbox = new QDoubleSpinBox(parent);
    spinbox->setMinimum(m_min);
    spinbox->setMaximum(m_max);
    spinbox->setDecimals(323);

    return spinbox;
}

void setEditorData(QWidget *editor,
                   const QModelIndex &index) const override {
    double value = index.model()->data(index, Qt::EditRole).toDouble();
    auto *spinBox = static_cast<QDoubleSpinBox *>(editor);
    spinBox->setValue(value);
}

void
setModelData(QWidget *editor, QAbstractItemModel *model,
             const QModelIndex &index) const override {
    auto *spinBox = static_cast<QDoubleSpinBox *>(editor);
    spinBox->interpretText();
    double value = spinBox->value();

    model->setData(index, value, Qt::EditRole);
}

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

};
 #include <QTableWidget> // table matrix box
 #include <QLabel>
 #include <QVBoxLayout>
 #include <QGridLayout>
 #include <QFileDialog>
 #include "intdelegate.h"
 #include "doubledelegate.h"
 #include <QComboBox> // selection of QT type
 #include <limits>


 #define CV_8U 0
 #define CV_8S 1
 #define CV_16U 2
 #define CV_16S 3
 #define CV_32S 4
 #define CV_32F 5
 #define CV_64F 6

// inside area where widget is created
class MatrixBoxWidget : public QWidget {
     Q_OBJECT

     QTableWidget *m_matrix_table;
     QComboBox *m_cv_types_combobox;
public:
 explicit MatrixBoxWidget(QWidget *parent = nullptr){
    m_cv_types_combobox = new QComboBox(this);

    m_cv_types_combobox->addItem("uint8", QVariant::fromValue(CV_8U));
    m_cv_types_combobox->addItem("int8", QVariant::fromValue(CV_8S));
    m_cv_types_combobox->addItem("uint16", QVariant::fromValue(CV_16U));
    m_cv_types_combobox->addItem("int16", QVariant::fromValue(CV_16S));
    m_cv_types_combobox->addItem("int32", QVariant::fromValue(CV_32S));
    m_cv_types_combobox->addItem("float", QVariant::fromValue(CV_32F));
    m_cv_types_combobox->addItem("double", QVariant::fromValue(CV_64F));


    connect(m_cv_types_combobox,
        qOverload<int>(&QComboBox::currentIndexChanged), this,
        &MatrixBoxWidget::validateDisplayType);

    QTableWidget *m_matrix_table = new QTableWidget(this);
    auto delegate = new IntDelegate();
    m_matrix_table->setItemDelegate(delegate);
    m_matrix_table->setItem(0, 0, new QTableWidgetItem());
    m_matrix_table->item(0, 0)->setData(Qt::EditRole, 12723);
    m_matrix_table->setItem(0, 1, new QTableWidgetItem());
    m_matrix_table->item(0, 1)->setData(Qt::EditRole, 12723);
    m_matrix_table->setItem(1, 0, new QTableWidgetItem());
    m_matrix_table->item(1, 0)->setData(Qt::EditRole, 12723);
    m_matrix_table->setItem(1, 1, new QTableWidgetItem());
    m_matrix_table->item(1, 1)->setData(Qt::EditRole, 12723);

    auto type_layout = new QVBoxLayout();
    auto type_label = new QLabel("type", this);
    type_layout->addWidget(type_label);
    type_layout->addWidget(m_cv_types_combobox);

    auto layout = new QGridLayout(this);
    layout->addLayout(type_layout, 0, 2);
    layout->addWidget(m_matrix_table, 1, 0, 3, 3);

}
void validateDisplayType(int index) {
    QVariant current_data = m_cv_types_combobox->currentData();
    auto cv_type = current_data.value<int>();
    QItemDelegate *delegate;
    switch (cv_type) {
        case CV_8U:
            delegate = new IntDelegate(std::numeric_limits<uint8_t>::min(),
                                       std::numeric_limits<uint8_t>::max());
            m_matrix_table->setItemDelegate(delegate);
            break;
        case CV_8S:
            delegate = new IntDelegate(std::numeric_limits<int8_t>::min(),
                                       std::numeric_limits<int8_t>::max());
            m_matrix_table->setItemDelegate(delegate);
            break;
        case CV_16U:
            delegate = new IntDelegate(std::numeric_limits<uint16_t>::min(),
                                       std::numeric_limits<uint16_t>::max());
            m_matrix_table->setItemDelegate(delegate);
            break;
        case CV_16S:
            delegate = new IntDelegate(std::numeric_limits<int16_t>::min(),
                                       std::numeric_limits<int16_t>::max());
            m_matrix_table->setItemDelegate(delegate);
            break;
        case CV_32S:
            delegate = new IntDelegate(std::numeric_limits<int32_t>::min(),
                                       std::numeric_limits<int32_t>::max());
            m_matrix_table->setItemDelegate(delegate);
            break;
        case CV_32F:
            delegate = new DoubleDelegate(-std::numeric_limits<float>::max(),
                                          std::numeric_limits<float>::max());
            m_matrix_table->setItemDelegate(delegate);
            break;
        case CV_64F:
            delegate = new DoubleDelegate(-std::numeric_limits<double>::max(),
                                          std::numeric_limits<double>::max());
            m_matrix_table->setItemDelegate(delegate);
            break;
        default:
            assert((false, "unknown type format"));
            break;
    }
};

例如,一个委托是一个uint16_t委托,我将该项的值设置为1024。当我交换委托时,我希望显示器相应地更改显示的值。当我去编辑一个项目时,它具有完美的行为,并且委托值变为255,并且类似地,如果我使用使用Doubles进行显示的委托,然后切换到整数,则从2.234转到2。操作,所有操作都使用相同的数字,但是当委托人更改并且为它限定了正确的范围(从uint16到uint8)时,我进行编辑:

enter image description here

当我切换委托而不是手动单击显示器时,如何以编程方式强制执行此行为?我尝试过更新视口,但是我不认为它会做我认为会做的事:

m_matrix_table->viewport()->update();

0 个答案:

没有答案