我有一个列值为0/1的数据库。
我使用QSqlRelationalTableModel向小部件显示数据。
是否可以在QComoboBox中为1显示Yes和为0显示No? 而且,当我选择是/否时,它应该保存到DB为1/0。
我可以使用setData()
和getData()
功能执行某些操作吗?有人能给出一个如何开始的线索吗?
更新
mpCountryModel->setTable("CountryMaster");
mpCountryModel->select();
ui->comboBox->setModel(mpCountryModel);
ui->comboBox->setModelColumn(5);
如第5列中的值为0或1,同样会显示0和1,右边?
答案 0 :(得分:0)
以下是literate programming样式的完整示例。让我们从标题和常用常量开始:
// https://github.com/KubaO/stackoverflown/tree/master/questions/proxy-combo-31995345
#include <QtWidgets>
#include <QtSql>
const QString kYes = QStringLiteral("Yes");
const QString kNo = QStringLiteral("No");
首先,您必须将数据库中的数据转换为适合显示和编辑的形式。要显示,您需要映射0-&gt;否和1-&gt;是。要进行编辑,您需要映射0-&gt; false和1-&gt; true,以便使用组合框编辑器。您需要一个代理模型:
/// Maps a given column from {0,1} to {false, true} for editing and {kNo, kYes} for display
class BoolProxy : public QIdentityProxyModel {
int m_column;
public:
BoolProxy(int column, QObject * parent = nullptr) :
QIdentityProxyModel{parent}, m_column{column} {}
QVariant data(const QModelIndex & index, int role) const override {
auto val = QIdentityProxyModel::data(index, role);
if (index.column() != m_column) return val;
if (role == Qt::DisplayRole || role == Qt::EditRole) {
if (val.toInt() == 0) {
if (role == Qt::DisplayRole) return kNo;
return false;
} else {
if (role == Qt::DisplayRole) return kYes;
return true;
}
}
return val;
}
bool setData(const QModelIndex & index, const QVariant & value, int role) override {
auto val = value;
if (index.column() == m_column && role == Qt::EditRole)
val = val.toBool() ? 1 : 0;
return QIdentityProxyModel::setData(index, val, role);
}
};
其次,您需要修改布尔组合框编辑器显示的条目。默认情况下,他们是&#34; True&#34;和&#34;错误&#34;。您需要将它们更改为&#34;是&#34;和&#34; No&#34;分别为:
class YesNoDelegate : public QStyledItemDelegate {
QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem &option,
const QModelIndex &index) const override {
auto ed = QStyledItemDelegate::createEditor(parent, option, index);
auto combo = qobject_cast<QComboBox*>(ed);
combo->setItemText(0, kNo);
combo->setItemText(1, kYes);
return ed;
}
};
让我们把它们放在一起:
int main(int argc, char ** argv) {
QApplication app{argc, argv};
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName(":memory:");
if (! db.open()) return 1;
db.exec("create table example (name text, inuse numeric);");
db.exec("insert into example (name, inuse) values "
"('Zaphod', 0), ('Beeblebrox', 1);");
QSqlTableModel model;
model.setTable("example");
model.select();
BoolProxy proxy{1};
proxy.setSourceModel(&model);
QTableView ui;
YesNoDelegate delegate;
ui.setItemDelegateForColumn(1, &delegate);
ui.setModel(&proxy);
ui.show();
return app.exec();
}
答案 1 :(得分:0)
这有什么好处吗?这对我有用。
TableModel* model = new TableModel(this);
ui->comboBox->setModel(model);
ui->comboBox->setModelColumn(TableModel::BoolColumn);
// ------------- tablemodel.h --------------------
QVariant data(const QModelIndex& index, int role) const;
int columnCount(const QModelIndex& ) const
{
return 2;
}
int rowCount(const QModelIndex& parentIndex) const
{
return parentIndex.isValid() ? 0 : 2;
}
// --------------------- tablemodel.cpp ----------------
QVariant TableModel::data(const QModelIndex& index, int role) const
{
if (!index.isValid() || index.row() > 2) {
return QVariant();
}
switch (role) {
case Qt::DisplayRole:
case Qt::EditRole:
if (index.column() == 0)
return tr("Column %1").arg(index.column());
else
if (index.row() % 2 == 0)
return "Yes";
else
return "No";
default:
break;
}
return QVariant();
}