Одна из первых проблем в работе с QTableWidget, которую пытаются решить, начавшие работать с этим виджетом - это установка QCheckBox в середине ячейки. Дело в том, что в стандартном чекбоксе в QTableWidget чекбокс привязан к левому краю ячейки, а правая часть отдаётся для пояснительного текста. Но текста может и не быть, а область всё равно остаётся. Но при этом QTableWidget позволяет устанавливать в свои ячейки виджеты, чем мы и воспользуемся для решения этой проблемы.
Данная статья является расширением предыдущей статьи по работе с QTableWidget , поэтому для просмотра полного кода проекта рекомендую обратиться также и к той статье. В данной статье приводится лишь код, необходимый для решения поставленной задачи.
Программный код был написан в QtCreator 3.3.1 на основе Qt 5.4.1.
Структура проекта для QCheckBox center
Структура проекта остаётся такой же, как и в предыдущей статье .
mainwindow.ui
Форма окна для приложения с QCheckBox В окне главного приложения будут помещены:
- QTableWidget
- QLable
mainwindow.cpp
Вместо стандартного чекбокса будет использован виджет с установленным в нём слоем, в котором будет содержаться QCheckBox, который будет расположен в центре виджета. Также будет продемонстрирован способ, как получить состояние чекбокса из этого виджета. В предыдущем уроке создавалась таблица с устройствами, и нечетные устройствами помечались отмеченными чекбоксами.
- #include "mainwindow.h"
- #include "ui_mainwindow.h"
- MainWindow::MainWindow(QWidget *parent) :
- QMainWindow(parent),
- ui(new Ui::MainWindow)
- {
- /* Программный код из предыдущего урока по QTableWidget */
- }
- MainWindow::~MainWindow()
- {
- delete ui;
- }
- /* Метод для настройки интерфейса,
- * в данном методе будет выполняться заполнение QTableWidget
- * записями из таблицы
- * */
- void MainWindow::createUI(const QStringList &headers)
- {
- /* Программный код из предыдущего урока по QTableWidget */
- // Создаём запрос для для выборки записей из базы данных
- QSqlQuery query("SELECT "
- DEVICE ".id, "
- DEVICE "." DEVICE_CHECK_STATE ", "
- DEVICE "." DEVICE_HOSTNAME ", "
- DEVICE "." DEVICE_IP ", "
- DEVICE "." DEVICE_MAC
- " FROM " DEVICE);
- /* Выполняем заполнение QTableWidget записями с помощью цикла
- * */
- for(int i = 0; query.next(); i++){
- // Вставляем строку
- ui->tableWidget->insertRow(i);
- /* Устанавливаем в первую колонку id забирая его из результата SQL-запроса
- * Эта колонка будет скрыта
- * */
- ui->tableWidget->setItem(i,0, new QTableWidgetItem(query.value(0).toString()));
- // Создаём виджет, который будет содержать в себе чекбокс
- QWidget *checkBoxWidget = new QWidget();
- QCheckBox *checkBox = new QCheckBox(); // объявляем и инициализируем чекбокс
- QHBoxLayout *layoutCheckBox = new QHBoxLayout(checkBoxWidget); // создаём слой с привязкой к виджету
- layoutCheckBox->addWidget(checkBox); // Устанавливаем чекбокс в слой
- layoutCheckBox->setAlignment(Qt::AlignCenter); // Отцентровываем чекбокс
- layoutCheckBox->setContentsMargins(0,0,0,0); // Устанавливаем нулевые отступы
- /* Проверяем, на статус нечетности, если нечетное устройство, то
- * выставляем состояние чекбокса в Checked, иначе в Unchecked
- * */
- if(query.value(1).toInt() == 1){
- checkBox->setChecked(true);
- } else {
- checkBox->setChecked(false);
- }
- // Устанавливаем чекбокс во вторую колонку
- ui->tableWidget->setCellWidget(i,1, checkBoxWidget);
- // Далее забираем все данные из результата запроса и устанавливаем в остальные поля
- ui->tableWidget->setItem(i,2, new QTableWidgetItem(query.value(2).toString()));
- ui->tableWidget->setItem(i,3, new QTableWidgetItem(query.value(3).toString()));
- ui->tableWidget->setItem(i,4, new QTableWidgetItem(query.value(4).toString()));
- }
- // Ресайзим колонки по содержимому
- ui->tableWidget->resizeColumnsToContents();
- /* В данном участке кода мы забираем состояния чекбоксов
- * и по порядку выводим их в QLabel
- * */
- QString str = QString("Состояния чекбоксов:"); // Подготавливаем строку для QLabel
- for(int i = 0; i < 4; i++){
- // Забираем виджет из ячейки
- QWidget *item = ( ui->tableWidget->cellWidget(i,1));
- // Забираем виджет из слоя и кастуем его в QCheckBox
- QCheckBox *checkB = qobject_cast <QCheckBox*> (item->layout()->itemAt(0)->widget());
- // Проверяем состояние чекбокса
- if(checkB->isChecked()){
- str += " 1 "; // добавляем к строку " 1 " , если состояние true
- } else {
- str += " 0 "; // в противном случае " 0 "
- }
- }
- // Устанавливаем текст в QLabel
- ui->label->setText(str);
- }
Итог
В результате получилось Приложение, которые выглядит следующим образом.
Приложение с QCheckBox в центре ячейки QTableWidget