ВК
Sept. 29, 2020, 8:08 p.m.

Как в QTableWidget, состоящей из чекбоксов, в строке таблицы можно было выбрать только один checkbox ?

QTableWidget, QCheckBox

Сделал таблицу состоящую из чекбоксов по уроку https://evileg.com/ru/post/78/
Кто-нибудь знает, как сделать так, чтобы в QTableWidget состоящей из чекбоксов в строке таблицы можно было выбрать только один checkbox ? Т.н. эксклюзивный чекбокс ?
Был бы весьма признателен за работающий пример.
По-хорошему хотелось бы также редактировать таблицу выбирая один чекбокс из списка чекбоксов в строках таблицы.
Можно ли генерировать автоматическое обновление таблицы без промежуточных действий, т.е. как только выбрал чекбокс автоматически выполняется SQL UPDATE таблицы.

Мой код по аналогии со статьей, но с небольшими доработками, здесь приведу отрывок:

  1. #include "mainwindow.h"
  2. #include "ui_mainwindow.h"
  3.  
  4. MainWindow::MainWindow(QWidget *parent) :
  5. QMainWindow(parent),
  6. ui(new Ui::MainWindow)
  7. {
  8. ui->setupUi(this);
  9.  
  10. this->setWindowTitle("Как сделать эксклюзивный чекбокс автобновление таблицы после его выбора");
  11.  
  12. db = new DataBase();
  13. db->connectToDataBase();
  14.  
  15. /* Вставка в базу данных записей */
  16. db->insertIntoTable(QVariantList() << "Тестовая запись №1"
  17. << ""
  18. << QString::number(false)
  19. << QString::number(false)
  20. << QString::number(false)
  21. << QString::number(false)
  22. << QString::number(false)
  23. << QString::number(false)
  24. << QString::number(false)
  25. << QString::number(false)
  26. << QString::number(false)
  27. << QString::number(false)
  28. << QString::number(false)
  29. << QString::number(false)
  30. );
  31. db->insertIntoTable(QVariantList() << "Тестовая запись №2"
  32. << ""
  33. << QString::number(false)
  34. << QString::number(false)
  35. << QString::number(false)
  36. << QString::number(false)
  37. << QString::number(false)
  38. << QString::number(false)
  39. << QString::number(false)
  40. << QString::number(false)
  41. << QString::number(false)
  42. << QString::number(false)
  43. << QString::number(false)
  44. << QString::number(false)
  45. );
  46. db->insertIntoTable(QVariantList() << "Тестовая запись №3"
  47. << ""
  48. << QString::number(false)
  49. << QString::number(false)
  50. << QString::number(false)
  51. << QString::number(false)
  52. << QString::number(false)
  53. << QString::number(false)
  54. << QString::number(false)
  55. << QString::number(false)
  56. << QString::number(false)
  57. << QString::number(false)
  58. << QString::number(false)
  59. << QString::number(false)
  60. );
  61.  
  62. /* Настраиваем внешний вид таблицы
  63. * с заданием названий колонок, а также
  64. * Заполняем таблицу записями из базы данных
  65. * */
  66. this->createUI(QStringList() << trUtf8("№")
  67. << trUtf8("Текстовое Поле №1")
  68. << trUtf8("Текстовое Поле №2")
  69. << trUtf8("Столбец чекбоксов №1")
  70. << trUtf8("Столбец чекбоксов №2")
  71. << trUtf8("Столбец чекбоксов №3")
  72. << trUtf8("Столбец чекбоксов №4")
  73. << trUtf8("Столбец чекбоксов №5")
  74. << trUtf8("Столбец чекбоксов №6")
  75. << trUtf8("Столбец чекбоксов №7")
  76. << trUtf8("Столбец чекбоксов №8")
  77. << trUtf8("Столбец чекбоксов №9"
  78. << trUtf8("Столбец чекбоксов №10")
  79. << trUtf8("Столбец чекбоксов №11")
  80. << trUtf8("Столбец чекбоксов №12")
  81. );
  82. }
  83.  
  84. MainWindow::~MainWindow()
  85. {
  86. delete ui;
  87. }
  88.  
  89. /* Настройка интерфейса - заполнение QTableWidget записями из таблицы
  90. * */
  91. void MainWindow::createUI(const QStringList &headers)
  92. {
  93. ui->tableWidget->setColumnCount(15); // Указываем число колонок
  94. ui->tableWidget->setShowGrid(true); // Включаем сетку
  95. // Разрешаем выделение только одного элемента
  96. ui->tableWidget->setSelectionMode(QAbstractItemView::SingleSelection);
  97. // Разрешаем выделение построчно
  98. ui->tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
  99. // Устанавливаем заголовки колонок
  100. ui->tableWidget->setHorizontalHeaderLabels(headers);
  101.  
  102. // Создаём запрос для для выборки записей из базы данных
  103. QSqlQuery query("SELECT "
  104. DBTABLE ".id, "
  105. DBTABLE "." TEXT1 ", "
  106. DBTABLE "." TEXT2 ", "
  107. DBTABLE "." CHECKBOX1 ", "
  108. DBTABLE "." CHECKBOX2 ", "
  109. DBTABLE "." CHECKBOX3 ", "
  110. DBTABLE "." CHECKBOX4 ", "
  111. DBTABLE "." CHECKBOX5 ", "
  112. DBTABLE "." CHECKBOX6 ", "
  113. DBTABLE "." CHECKBOX7 ", "
  114. DBTABLE "." CHECKBOX8 ", "
  115. DBTABLE "." CHECKBOX9 ", "
  116. DBTABLE "." CHECKBOX10 ", "
  117. DBTABLE "." CHECKBOX11 ", "
  118. DBTABLE "." CHECKBOX12
  119. " FROM " DBTABLE);
  120.  
  121. /* Выполняем заполнение QTableWidget записями
  122. * */
  123. for(int i = 0; query.next(); i++){
  124. ui->tableWidget->insertRow(i);
  125. /* Устанавливаем в первую колонку id забирая его из результата SQL-запроса
  126. * */
  127. ui->tableWidget->setItem(i,0, new QTableWidgetItem(query.value(0).toString()));
  128.  
  129. // Создаём элементы, который будет выполнять роль чекбоксов
  130. QTableWidgetItem *item1 = new QTableWidgetItem();
  131. item1->data(Qt::CheckStateRole);
  132. item1->setCheckState(Qt::Unchecked);
  133. QTableWidgetItem *item2 = new QTableWidgetItem();
  134. item2->data(Qt::CheckStateRole);
  135. item2->setCheckState(Qt::Unchecked);
  136. QTableWidgetItem *item3 = new QTableWidgetItem();
  137. item3->data(Qt::CheckStateRole);
  138. item3->setCheckState(Qt::Unchecked);
  139. QTableWidgetItem *item4 = new QTableWidgetItem();
  140. item4->data(Qt::CheckStateRole);
  141. item4->setCheckState(Qt::Unchecked);
  142. QTableWidgetItem *item5 = new QTableWidgetItem();
  143. item5->data(Qt::CheckStateRole);
  144. item5->setCheckState(Qt::Unchecked);
  145. QTableWidgetItem *item6 = new QTableWidgetItem();
  146. item6->data(Qt::CheckStateRole);
  147. item6->setCheckState(Qt::Unchecked);
  148. QTableWidgetItem *item7 = new QTableWidgetItem();
  149. item7->data(Qt::CheckStateRole);
  150. item7->setCheckState(Qt::Unchecked);
  151. QTableWidgetItem *item8 = new QTableWidgetItem();
  152. item8->data(Qt::CheckStateRole);
  153. item8->setCheckState(Qt::Unchecked);
  154. QTableWidgetItem *item9 = new QTableWidgetItem();
  155. item9->data(Qt::CheckStateRole);
  156. item9->setCheckState(Qt::Unchecked);
  157. QTableWidgetItem *item10 = new QTableWidgetItem();
  158. item10->data(Qt::CheckStateRole);
  159. item10->setCheckState(Qt::Unchecked);
  160. QTableWidgetItem *item11 = new QTableWidgetItem();
  161. item11->data(Qt::CheckStateRole);
  162. item11->setCheckState(Qt::Unchecked);
  163. QTableWidgetItem *item12 = new QTableWidgetItem();
  164. item12->data(Qt::CheckStateRole);
  165. item12->setCheckState(Qt::Unchecked);
  166. QTableWidgetItem *item24 = new QTableWidgetItem();
  167. item24->data(Qt::CheckStateRole);
  168. item24->setCheckState(Qt::Unchecked);
  169.  
  170. ui->tableWidget->setItem(i,1, new QTableWidgetItem(query.value(1).toString()));
  171. ui->tableWidget->setItem(i,2, new QTableWidgetItem(query.value(2).toString()));
  172.  
  173. // Устанавливаем чекбоксы в остальные колонки:
  174. ui->tableWidget->setItem(i,3, item1);
  175. ui->tableWidget->setItem(i,4, item2);
  176. ui->tableWidget->setItem(i,5, item3);
  177. ui->tableWidget->setItem(i,6, item4);
  178. ui->tableWidget->setItem(i,7, item5);
  179. ui->tableWidget->setItem(i,8, item6);
  180. ui->tableWidget->setItem(i,9, item7);
  181. ui->tableWidget->setItem(i,10, item8);
  182. ui->tableWidget->setItem(i,11, item9);
  183. ui->tableWidget->setItem(i,12, item10);
  184. ui->tableWidget->setItem(i,13, item11);
  185. ui->tableWidget->setItem(i,14, item12);
  186. ui->tableWidget->setItem(i,15, item24);
  187. }
  188. ui->tableWidget->resizeColumnsToContents();
  189. }
  190.  

UPDATED_TODAY)))):
По поводу того, как сделать эксклюзивный чекбокс мысли следующие: Если пользователь задействует любой из находящихся в строке отображаемой
таблицы(QTableView), то перебираются все чекбосы, кроме задействованного эксклюзивного чекбокса и их состояние активности ставится в ->setCheckState(Qt::Unchecked); непонятно как это правильно сделать, а именно как перебрать все элементы таблицы в строке. А может быть вообще все делается проще и не надо тут фантазировать ?

2
The question is asked by the articleQt/C++ - Lesson 015. QTableWidget – How to create a table with checkboxes?

Do you like it? Share on social networks!

1
Evgenii Legotckoi
  • Oct. 8, 2020, 3:32 a.m.

Наверное, лучше всё-таки вам посмотреть в сторону QSqlTableModel и использовать QTableView вместо QTableWidget.
В том случае можно будет у модели переопределить метод setData и внутри него переустанавливать все остальные чекбоксы.
Единственное, возможно, что нужно будет переопределить метод flags, чтобы сообщить модели, что это всё checkable колонки.

    Comments

    Only authorized users can post comments.
    Please, Log in or Sign up
    • Last comments
    • AK
      April 1, 2025, 11:41 a.m.
      Добрый день. В данный момент работаю над проектом, где необходимо выводить звук из программы в определенное аудиоустройство (колонки, наушники, виртуальный кабель и т.д). Пишу на Qt5.12.12 поско…
    • Evgenii Legotckoi
      March 9, 2025, 9:02 p.m.
      К сожалению, я этого подсказать не могу, поскольку у меня нет необходимости в обходе блокировок и т.д. Поэтому я и не задавался решением этой проблемы. Ну выглядит так, что вам действитель…
    • VP
      March 9, 2025, 4:14 p.m.
      Здравствуйте! Я устанавливал Qt6 из исходников а также Qt Creator по отдельности. Все компоненты, связанные с разработкой для Android, установлены. Кроме одного... Когда пытаюсь скомпилиров…
    • ИМ
      Nov. 22, 2024, 9:51 p.m.
      Добрый вечер Евгений! Я сделал себе авторизацию аналогичную вашей, все работает, кроме возврата к предидущей странице. Редеректит всегда на главную, хотя в логах сервера вижу запросы на правильн…
    • Evgenii Legotckoi
      Oct. 31, 2024, 11:37 p.m.
      Добрый день. Да, можно. Либо через такие же плагины, либо с постобработкой через python библиотеку Beautiful Soup