Ruslan Polupan24 квітня 2019 р. 06:07
Помогите разобраться с CheckBox delegate в QAbstractTableModel
Delegate, qcheckbox, QAbstractTableModel
Доброго времени суток.
Где то я упустил что-то при изучении делегатов и их использовании.
Отображение работает. Но после того как выбираешь другую строку таблицы, предидущее выделение сбрсывается.
Не получается выбрать несколько объектов.
Файлы реализации делегата CheckBoxDelegate использовал такие же как в этой статье https://evileg.com/ru/post/478/
Реализация модели
modelterminals.h
#ifndef MODELTERMINALS_H #define MODELTERMINALS_H #include "terminalclass.h" #include <QObject> #include <QAbstractTableModel> class ModelTerminals : public QAbstractTableModel { Q_OBJECT QList<TerminalClass> m_listTerm; public: ModelTerminals(QList<TerminalClass> lsTerm); // QAbstractItemModel interface public: int rowCount(const QModelIndex &parent) const; int columnCount(const QModelIndex &parent) const; QVariant data(const QModelIndex &index, int role) const; bool setData(const QModelIndex &index, const QVariant &value, int role); Qt::ItemFlags flags(const QModelIndex &index) const; QVariant headerData(int section, Qt::Orientation orientation, int role) const; }; #endif // MODELTERMINALS_H
modelterminals.cpp
#include "modelterminals.h" ModelTerminals::ModelTerminals(QList<TerminalClass> lsTerm ) : m_listTerm(lsTerm) { } int ModelTerminals::rowCount(const QModelIndex &parent) const { return m_listTerm.size(); Q_UNUSED(parent) } int ModelTerminals::columnCount(const QModelIndex &parent) const { return m_listTerm.at(0).colParam(); Q_UNUSED(parent) } QVariant ModelTerminals::data(const QModelIndex &index, int role) const { if(!index.isValid()) { return QVariant();} TerminalClass t = m_listTerm[index.row()]; switch (role) { case Qt::DisplayRole: switch (index.column()) { case 0: return t.isCheced(); case 1: return t.terminalID(); case 2: return t.terminalName(); case 3: return t.regionID(); case 4: return t.serverName(); } break; case Qt::CheckStateRole: if(index.column() == 0) { return (!t.isCheced()) ? Qt::Checked : Qt::Unchecked; } break; default: break; } return QVariant(); } bool ModelTerminals::setData(const QModelIndex &index, const QVariant &value, int role) { if(!index.isValid()) {return false;} TerminalClass t = m_listTerm[index.row()]; if(role == Qt::CheckStateRole){ if(value.toInt() == Qt::Checked){ t.setIsCheced(true); } else { t.setIsCheced(false); } emit dataChanged(index,index); return true; } return false; } Qt::ItemFlags ModelTerminals::flags(const QModelIndex &index) const { Qt::ItemFlags flags = QAbstractTableModel::flags(index); if(index.isValid() && index.column() == 0){ flags |= Qt::ItemIsEditable; } return flags; } QVariant ModelTerminals::headerData(int section, Qt::Orientation orientation, int role) const { if( role != Qt::DisplayRole) { return QVariant();} if( orientation == Qt::Vertical ) { return section; } switch (section) { case 0: return ""; case 1: return "АЗС"; case 2: return "Адрес"; case 3: return "Регион"; case 4: return "Сервер"; default: break; } return QVariant(); }
Получаю данные для модели и создаю модель
#include "fuelnamedialog.h" #include "ui_fuelnamedialog.h" FuelNameDialog::FuelNameDialog(QWidget *parent) : QDialog(parent), ui(new Ui::FuelNameDialog) { ui->setupUi(this); createListTerminals(); createModelterminals(); } FuelNameDialog::~FuelNameDialog() { delete ui; } void FuelNameDialog::createModelterminals() { qInfo(logInfo()) << "Заружено терминалов:" << listTerminals.size(); CheckBoxDelegate *delegate = new CheckBoxDelegate(); modelTerminals = new ModelTerminals(listTerminals); ui->tableViewTerminals->setModel(modelTerminals); ui->tableViewTerminals->setItemDelegateForColumn(0,delegate); ui->tableViewTerminals->verticalHeader()->hide(); ui->tableViewTerminals->resizeColumnsToContents(); } void FuelNameDialog::createListTerminals() { QSqlQuery q; TerminalClass t; if(!q.exec("SELECT t.TERMINAL_ID, TRIM(t.name) AS NAME, t.OWNER_ID AS REGION, c.SERVER_NAME FROM TERMINALS t " "LEFT JOIN CONNECTIONS c ON c.TERMINAL_ID = t.TERMINAL_ID " "WHERE t.TERMINALTYPE = 3 AND c.CONNECT_ID = 2 " "ORDER BY t.TERMINAL_ID")) { qInfo(logInfo()) << Q_FUNC_INFO << "Не возможно получить список терминалов" << q.lastError().text(); return; } while(q.next()){ t.setIsCheced(false); t.setTerminalID(q.value(0).toInt()); t.setTerminalName(q.value(1).toString()); t.setRegionID(q.value(2).toInt()); t.setServerName(q.value(3).toString()); listTerminals.append(t); } }
Рекомендуємо хостинг TIMEWEB
Стабільний хостинг, на якому розміщується соціальна мережа EVILEG. Для проектів на Django радимо VDS хостинг.Вам це подобається? Поділіться в соціальних мережах!
sf
- sdfsdfkp fgskpgokspdog
- 14 жовтня 2024 р. 15:09
C++ - Тест 004. Указатели, Массивы и Циклы
- Результат:90бали,
- Рейтинг балів8
МВ
- Максим Васильев
- 02 жовтня 2024 р. 04:14
Qt - Тест 001. Сигналы и слоты
- Результат:68бали,
- Рейтинг балів-1
ЛС
- Лев Семенов
- 30 вересня 2024 р. 11:04
C++ - Тест 001. Первая программа и типы данных
- Результат:53бали,
- Рейтинг балів-4
Останні коментарі
Читалка файлів fb3 на Qt Creator Подскажите как это запустить? Я не шарю в программировании и кодинге. Скачал и установаил Qt, но куча ошибок выдается и не запустить. А очень надо fb3 переконвертировать в html
ИМ
Django - Урок 064. Як написати розширення для Python Markdown Приветствую Евгений! У меня вопрос. Можно ли вставлять свои классы в разметку редактора markdown? Допустим имея стандартную разметку: <ul> <li></li> <li></l…
Игорь Максимов05 жовтня 2024 р. 07:51
QML - Урок 016. База даних SQLite та робота з нею в QML Qt Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
Qt Linux - Урок 001. Автозапуск програми Qt під Linux как сделать автозапуск для флэтпака, который не даёт создавать файлы в ~/.config - вот это вопрос ))
АК
Qt WinAPI - Урок 007. Робота з ICMP Ping в Qt Без строки #include <QRegularExpressionValidator> в заголовочном файле не работает валидатор.
Анатолий Кононенко05 лютого 2024 р. 01:50
Тепер обговоріть на форумі
добавить qlineseries в функции Пользователь может получить любые разъяснения по интересующим вопросам, касающимся обработки его персональных данных, обратившись к Оператору с помощью электронной почты https://topdecorpro.ru…
ИМ
Реализация навигации по разделам Спасибо Евгений!
Игорь Максимов03 жовтня 2024 р. 04:05
Indian Food Restaurant In Columbus OH| Layla’s Kitchen Indian Restaurant If you're looking for a truly authentic https://www.laylaskitchenrestaurantohio.com/ , Layla’s Kitchen Indian Restaurant is your go-to destination. Located at 6152 Cleveland Ave, Colu…
КГ
Не запускается программа на Qt: точка входа в процедуру не найдена в библиотеке DLL Написал программу на C++ Qt в Qt Creator, сбилдил Release с помощью MinGW 64-bit, бинарнику напихал dll-ки с помощью windeployqt.exe. При попытке запуска моей сбилженной программы выдаёт три оши…
Кирилл Гусарев27 вересня 2024 р. 09:09
при создании qml проекта Kits есть но недоступны для выбора Поставил Qt Creator 11.0.2. Qt 6.4.3 При создании проекта Qml не могу выбрать Kits, они все недоступны, хотя настроены и при создании обычного Qt Widget приложения их можно выбрать. В чем может …
Добрый день
А вот этот код
Не должен быть написан так?
Согласен. но ситуация не поменялась. Такое чуство что данные не записываются в модель.
Думаю, что в методе setData нужно в роли Qt::EditRole делать установку значения. Скорее всего у вас просто не заходит в ту ветку кода выполнение программы. Обычно для установки значения используется именно роль Qt::EditRole
Изменил функцию
теперь работает.
Продолжаем вопросы... (Сори если что :-)
Как теперь отловить сигнал checked от делегата?
Пока сделал так:
Где:
но это отрабатывает изменение модели
А вот сам клик на checkbox бы отловить...
Ну по идее есть такой сигнал commitData у делегатов. В данном сигнале высылается указатель на виджет перед записью данных в модель. Можете попробовать на его основе что-то сообразить.
Еще обнаружил такую ситуацию. Оказывается данные в модель записываются, лиш после того как фокус получает любой item TableView.
Т.е. Состояние CheckBox записывается в модель не при изменении его статуса а лишь тогда когда с него теряется фокус.
Ну в общем-то да, есть такая ситуация. Думаю, что это правильное поведение. Дело в том, что если логика под капотом очень сложная и влияет на большое количество компонентов, то апдейт при редактировании может очень сильно уменьшить скорость работы софта, поскольку такие апдейты будут выполняться тогда, когда по факту в 99% случае они вовсе не нужны.
Реализовать такую ситуацию:
Я выбрал несколько строк и не прешел на другую ячейку а нажал кнопку "Выполнить" например.
И тогда получается что последняя мною выбранная запись не попадет для дальнейшей обработки.
Или есть таки способ принудительно опросить делегаты и записать их состояние в модель?