Evgenii Legotckoi
4 сентября 2015 г. 21:54

Qt/C++ - Урок 016. Как установить QCheckBox в центре ячейки QTableWidget

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

Вам это нравится? Поделитесь в социальных сетях!

Комментарии

Только авторизованные пользователи могут публиковать комментарии.
Пожалуйста, авторизуйтесь или зарегистрируйтесь
  • Последние комментарии
  • Evgenii Legotckoi
    16 апреля 2025 г. 17:08
    Благодарю за отзыв. И вам желаю всяческих успехов!
  • IscanderChe
    12 апреля 2025 г. 17:12
    Добрый день. Спасибо Вам за этот проект и отдельно за ответы на форуме, которые мне очень помогли в некоммерческих пет-проектах. Профессиональным программистом я так и не стал, но узнал мно…
  • AK
    1 апреля 2025 г. 11:41
    Добрый день. В данный момент работаю над проектом, где необходимо выводить звук из программы в определенное аудиоустройство (колонки, наушники, виртуальный кабель и т.д). Пишу на Qt5.12.12 поско…
  • Evgenii Legotckoi
    9 марта 2025 г. 21:02
    К сожалению, я этого подсказать не могу, поскольку у меня нет необходимости в обходе блокировок и т.д. Поэтому я и не задавался решением этой проблемы. Ну выглядит так, что вам действитель…
  • VP
    9 марта 2025 г. 16:14
    Здравствуйте! Я устанавливал Qt6 из исходников а также Qt Creator по отдельности. Все компоненты, связанные с разработкой для Android, установлены. Кроме одного... Когда пытаюсь скомпилиров…