Одна из первых проблем в работе с 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