我可以在QComboBox中将模型中的bool转换为yes / no

时间:2015-08-13 18:00:38

标签: c++ qt

我有一个列值为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,右边?

2 个答案:

答案 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;
    }
};

让我们把它们放在一起:

screenshot of the example

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();
}