Столбец только для флажка в QTableView

У меня есть таблица в базе данных Sqlite, которую я отображаю с помощью QTableview и QSqlQueryModel. Первый столбец должен иметь заголовок, который является флажком, и все элементы в столбце также должны быть флажками. Я реализовал заголовок первого столбца как флажок, и он отлично работает.

Поскольку флажки в столбце должны быть центрированы, я использовал делегат, чтобы нарисовать его. Я нарисовал флажки, используя следующий код, но их нельзя ни отметить, ни снять. Я не знаю, как это реализовать.

static QRect CheckBoxRect(const QStyleOptionViewItem &view_item_style_options) {
   QStyleOptionButton check_box_style_option;
   QRect check_box_rect = QApplication::style()->subElementRect(
   QStyle::SE_CheckBoxIndicator,
   &check_box_style_option);
   QPoint check_box_point(view_item_style_options.rect.x() +
                     view_item_style_options.rect.width() / 2 -
                     check_box_rect.width() / 2,
                     view_item_style_options.rect.y() +
                     view_item_style_options.rect.height() / 2 -
                     check_box_rect.height() / 2);
   return QRect(check_box_point, check_box_rect.size());
}


CheckBoxDelegate::CheckBoxDelegate(QObject *parent) :
QStyledItemDelegate(parent)
{

}

void CheckBoxDelegate::paint(QPainter *painter,
                         const QStyleOptionViewItem &option,
                         const QModelIndex &index) const {
  bool checked = index.model()->data(index, Qt::DisplayRole).toBool();

  QStyleOptionButton check_box_style_option;
  check_box_style_option.state |= QStyle::State_Enabled;
  if (checked) {
    check_box_style_option.state |= QStyle::State_On;
  } else {
    check_box_style_option.state |= QStyle::State_Off;
  }
  check_box_style_option.rect = CheckBoxRect(option);

  QApplication::style()->drawControl(QStyle::CE_CheckBox,
                                 &check_box_style_option,
                                 painter);
}

В следующем коде показано, как я использую QSqlQueryModel для QTableView для загрузки таблицы из базы данных.

//Load the tableview with the database table
QSqlQueryModel model = new QSqlQueryModel();

//Initializaton of the query
QSqlQuery *query = new QSqlQuery(dbm->db);

query->prepare("SELECT * FROM UserData");

if(query->exec())
{
    model->setQuery(*query);
    ui->tableView->setModel(model);

    //The header delegate to paint a checkbox on the header
    HeaderDelegate *myHeader = new HeaderDelegate(Qt::Horizontal, ui->tableView);
    ui->tableView->setHorizontalHeader(myHeader);

    int RowCount = model->rowCount();

    qDebug() << RowCount;

    CheckBoxDelegate *myCheckBoxDelegate = new CheckBoxDelegate();

    ui->tableView->setItemDelegateForColumn(0,myCheckBoxDelegate);

    ui->tableView->horizontalHeader()->setClickable(true);

    ui->tableView->setSortingEnabled(true);
}

Не могли бы вы рассказать мне, как это сделать? Любая помощь приветствуется.


person gfernandes    schedule 28.01.2014    source источник


Ответы (2)


Я нашел это решение, которое не использует делегатов или что-то в этом роде. У вас все еще будет проблема с центрированием флажка. Это зависит от вас.

Следующий фрагмент кода создаст столбец, заполненный флажками:

yourSqlQueryModel = new QSqlQueryModel();
yourTableView = new QtableView();
        yourSqlQueryModel ->setQuery(yourQuery);
        yourSqlQueryModel ->insertColumn(0);//Insert column for checkboxes
        ui->yourTableView ->setModel(yourSqlQueryModel );
        ui->yourTableView ->resizeColumnsToContents();

        int p;
        for(p = 0;p<yourSqlQueryModel ->rowCount();p++)
        {
            ui->yourTableView ->setIndexWidget(yourSqlQueryModel ->index(p,0),new QCheckBox());
        }

Пожалуйста, внимательно прочитайте, здесь самым важным является метод setIndexWidget, который позволяет вставить виджет в созданную колонку.

person Jorge Aguilera Perez    schedule 05.05.2014
comment
Заявление Trolltech для setIndexWidget: This function should only be used to display static content within the visible area corresponding to an item of data. If you want to display custom dynamic content or > implement a custom editor widget, subclass QItemDelegate instead. Следует также отметить, что это нарушает шаблон Model/View. Вместо этого следует отдавать предпочтение пользовательским подклассам QItemDelegate. - person Folling; 18.11.2019

Самый простой способ отобразить проверяемые элементы — использовать QStandardItemModel, так как QStandardItem можно установить проверяемым. Это хорошо для прототипирования. Однако недостатком является то, что вам приходилось заполнять модель вручную.

person Valentin Heinitz    schedule 28.01.2014