我正在为SQLite数据库在Qt5中开发一个GUI。我使用QSqlQueryModel和QTableView来存储和显示数据。
然后,我创建了一个自定义委托,使用开关语句将某些列的数值替换为表视图中的文字(例如1= "Hello",2= "World")。
委托以应有的方式显示数据,并在功能上工作。但是,与QStyledItemDelegate的默认画法相比,自定义委托绘制的列具有不同的格式。值位于左上角而不是左上角,更改后的列不再自动展开以显示全部值,列中的单元格在选择时不会变成蓝色或虚线轮廓。
我创建了这个示例程序:
#include <QApplication>
#include <QModelIndex>
#include <QPainter>
#include <QStandardItemModel>
#include <QStyledItemDelegate>
#include <QTableView>
class TestDelegate: public QStyledItemDelegate {
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index)
const Q_DECL_OVERRIDE
{
if (index.column() == 0) {
int value = index.model()->data(index, Qt::DisplayRole).toInt();
QString str;
switch (value) {
case 1:
str = "Hello0000";
break;
case 2:
str = "World0000";
break;
}
if (option.state.testFlag (QStyle::State_Selected)) {
painter->fillRect(option.rect, option.palette.highlight());
qApp->style()->drawItemText(painter, option.rect, option.displayAlignment, option.palette, true, str, QPalette::HighlightedText);
} else {
painter->drawText(option.rect, option.displayAlignment, str);
}
} else {
return QStyledItemDelegate::paint(painter, option, index);
}
}
};
int main(int argc, char **argv) {
QApplication app(argc, argv);
QStandardItemModel model(2, 2);
model.setHorizontalHeaderItem(0, new QStandardItem(QString("A")));
model.setHorizontalHeaderItem(1, new QStandardItem(QString("B")));
model.setData(model.index(0, 0, QModelIndex()), 1);
model.setData(model.index(1, 0, QModelIndex()), 2);
model.setItem(0, 1, new QStandardItem(QString("Hello")));
model.setItem(1, 1, new QStandardItem(QString("World0000")));
QTableView view;
view.setItemDelegate(new TestDelegate);
view.setModel(&model);
view.resizeColumnsToContents();
view.show();
app.exec();
}这通过将options.displayAlignment添加到painter->drawText()来修正文本对齐问题;我还在if(option.state & QStyle::State_Selected)语句中添加了其他代码,根据单元格的选择状态绘制单元格。因此,如果它没有被选中,文本是黑色的,如果是的话,文本变成白色,背景变成蓝色。但是,我仍然不能让列展开以适应单元格的内容,也不能像对标准委托那样在单元格的外部添加虚线。
在使用我的自定义画法时,是否有一种简单的方法来维护表视图的默认样式?
发布于 2016-08-31 20:26:29
委托是一种相当迂回和不必要的方式。我们已经有了一个视图,可以很好地绘制元素,不需要重做。我们只需要将修改过的数据传递给视图。因此,我们在源视图和视图之间插入一个QIdentityProxyModel视图模型。
// https://github.com/KubaO/stackoverflown/tree/master/questions/proxy-reformat-39244309
#include <QtWidgets>
class RewriteProxy : public QIdentityProxyModel {
QMap<QVariant, QVariant> m_read, m_write;
int m_column;
public:
RewriteProxy(int column, QObject * parent = nullptr) :
QIdentityProxyModel{parent}, m_column{column} {}
void addReadMapping(const QVariant & from, const QVariant & to) {
m_read.insert(from, to);
m_write.insert(to, from);
}
QVariant data(const QModelIndex & index, int role) const override {
auto val = QIdentityProxyModel::data(index, role);
if (index.column() != m_column) return val;
auto it = m_read.find(val);
return it != m_read.end() ? it.value() : val;
}
bool setData(const QModelIndex & index, const QVariant & value, int role) override {
auto val = value;
if (index.column() == m_column) {
auto it = m_write.find(value);
if (it != m_write.end()) val = it.value();
}
return QIdentityProxyModel::setData(index, val, role);
}
};
int main(int argc, char ** argv) {
QApplication app{argc, argv};
QStandardItemModel model{2,2};
model.setData(model.index(0, 0), 1);
model.setData(model.index(1, 0), 2);
model.setData(model.index(0, 1), "Zaphod");
model.setData(model.index(1, 1), "Beeblebrox");
RewriteProxy proxy{0};
proxy.setSourceModel(&model);
proxy.addReadMapping(1, "Hello");
proxy.addReadMapping(2, "World");
QTableView ui;
ui.setModel(&proxy);
ui.show();
return app.exec();
}https://stackoverflow.com/questions/39244309
复制相似问题