我创建了一个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)时,我进行编辑:
当我切换委托而不是手动单击显示器时,如何以编程方式强制执行此行为?我尝试过更新视口,但是我不认为它会做我认为会做的事:
m_matrix_table->viewport()->update();