Изменение цвета в QTableView по нажатию кнопки

134
08 января 2021, 16:00

Всем привет. Подскажите пожалуйста, как изменить цвет в Qt QTableView для текущей позиции в таблице по нажатию на кнопку? Задача такая: Пользователь добавляет в таблицу запись и она выделена допустим жёлтым, администратор БД по нажатию на кнопку должен подтвердить, что запись корректна и изменить цвет на обычный. Я реализовал создание и загрузку Бд, могу менять цвет по условию через кастомный делегат, но ещё сильно туплю и не могу понять как вывести изменение цвета на кнопку. Также могу определить выбранную ячейку.

Answer 1

Я бы посоветовал вам добавить в вашу таблицу записей в БД поле статуса, которое будет обозначать, проверена запись или нет.

Предположим у нас есть такая таблица:

create table person (id int primary key, firstname varchar(20), lastname varchar(20), status int)

На мой взгляд, удобнее будет не использовать делегаты, а унаследовать свою модель от класса QSqlQueryModel:

#include <QSqlQueryModel>
#include <QColor>
#include <QBrush>
#include <QSqlQuery>
class MyModel : public QSqlQueryModel
{
public:
    // Константы, хранящие нужные индексы колонок
    enum { kIdColumn = 0 /* индекс колонки с id */, kStatusColumn = 3 /* индекс колонки со статусом */};
    int getStatusOfRow(int rowIndex) const {
        return data(index(rowIndex, kStatusColumn ),Qt::EditRole).toInt();
    }
    QVariant data(const QModelIndex &itemIndex, int role = Qt::DisplayRole) const override
    {
        if (role == Qt::BackgroundRole) {
            int status = getStatusOfRow(itemIndex.row());
            int row = itemIndex.row();
            if (status == 0 ) {
                return QBrush(QColor(255, 255, 0));
            }
        } else if (role == Qt::DisplayRole) {
            if (itemIndex.column() == kStatusColumn) {
                int status = getStatusOfRow(itemIndex.row());
                return status ? "Verified" :  "Unverified";
            }
        }
        return QSqlQueryModel::data(itemIndex, role);
    }
    bool setStatus(int personId, int status) {
        QSqlQuery query;
        query.prepare("update person set status = ? where id = ?");
        query.addBindValue(status);
        query.addBindValue(personId);
        return query.exec();
    }
};

В методе data() нужно переопределить в первую очередь поведение при role == Qt::BackgroundRole, чтобы поменять цвет фона. В данном примере также обрабатывается случай Qt::DisplayRole для колонки со статусом, чтобы выводить текст Verified/Unverified вместо 1 или 0.

TableView инициализируется следующим образом:

MyModel* model = new MyModel(this);
model->setQuery("select * from person");
model->setHeaderData(0, Qt::Horizontal, QObject::tr("ID"));
model->setHeaderData(1, Qt::Horizontal, QObject::tr("First name"));
model->setHeaderData(2, Qt::Horizontal, QObject::tr("Last name"));
model->setHeaderData(3, Qt::Horizontal, QObject::tr("Status"));
QTableView *view = new QTableView(parent);
view->setModel(model);
view->setSelectionBehavior(QAbstractItemView::SelectRows);

При нажатии на кнопку выполняем следующий код:

void MainWindow::pushButtonClick() {
    QModelIndexList list = view->selectionModel()->selectedRows();
    if (!list.empty()) {
        int rowIndex = list.at(0).row();
        int personId = model->data(model->index(rowIndex, MyModel::kIdColumn)).toInt();
        int statusId = model->getStatusOfRow(rowIndex);
        if (statusId == 0) {
            model->setStatus(personId, 1);
            refreshModel(model);
        }
    }
}
void MainWindow::refreshModel(QSqlQueryModel *model) {
    model->setQuery("select * from person");
}

При нажатии на кнопку сначала мы получаем индексы выделенных элементов, берем первую строку (можно переделать для множественного выделения), обращаемся к модели и получаем id и status записи. Обновляем запись в БД и обновляем содержимое TableView путем повторного присвоения того же самого запроса.

В итоге получаем такой результат:

READ ALSO
Ошибка при выполнении cmake

Ошибка при выполнении cmake

Я запускаю команду:

116
TON compile error c++ cmake

TON compile error c++ cmake

На 83% ошибка:

91
Передать значение из одной функции в другую функцию?

Передать значение из одной функции в другую функцию?

Как из функции add_matrix_A и add_matrix_B предать N и M в функцию matrix_C?

120
С++: непонятная ошибка C2244

С++: непонятная ошибка C2244

Есть класс считывания данные из файла выполненный через итератор:

100