Qt QTableView如何只有一个复选框列 [英] Qt QTableView how to have a checkbox only column
问题描述
我们正在Qt 4.6.3中使用QTableView
,并且需要一个在每个单元格中仅具有一个复选框的列.我们使用QAbstractTableModel
的自定义子类作为QTableView
的模型.现在,我们通过设置Qt::ItemIsUserCheckable
标志有一个复选框.但是我们不知道如何摆脱复选框旁边的空白文本框!
We are using a QTableView
with Qt 4.6.3, and need a column that only has a checkbox in each cell. We're using a custom subclass of QAbstractTableModel
as the model for the QTableView
. Right now, we have a checkbox by setting the Qt::ItemIsUserCheckable
flag. But we can't figure out how to get rid of the blank textbox next to the checkbox!
我们如何才能使列"仅"具有复选框,而没有其他内容?
How can we make the column only have a checkbox, nothing else?
推荐答案
这是一个解决方案.为了使此功能正常运行,您的列应不设置Qt::ItemIsEditable
或Qt::ItemIsUserCheckable
标志.这会从Qt::DisplayRole
读取布尔值,并用Qt::EditRole
调用setData()
(即否 Qt::CheckStateRole
.)
Here is a solution. For this to work properly, your column should not have the Qt::ItemIsEditable
or Qt::ItemIsUserCheckable
flags set. This reads the boolean values from Qt::DisplayRole
and calls setData()
with Qt::EditRole
(i.e. not Qt::CheckStateRole
.)
#include "check_box_delegate.h"
#include <QtGui/QApplication>
#include <QtGui/QMouseEvent>
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);
}
// This is essentially copied from QStyledItemEditor, except that we
// have to determine our own "hot zone" for the mouse click.
bool CheckBoxDelegate::editorEvent(QEvent *event,
QAbstractItemModel *model,
const QStyleOptionViewItem &option,
const QModelIndex &index) {
if ((event->type() == QEvent::MouseButtonRelease) ||
(event->type() == QEvent::MouseButtonDblClick)) {
QMouseEvent *mouse_event = static_cast<QMouseEvent*>(event);
if (mouse_event->button() != Qt::LeftButton ||
!CheckBoxRect(option).contains(mouse_event->pos())) {
return false;
}
if (event->type() == QEvent::MouseButtonDblClick) {
return true;
}
} else if (event->type() == QEvent::KeyPress) {
if (static_cast<QKeyEvent*>(event)->key() != Qt::Key_Space &&
static_cast<QKeyEvent*>(event)->key() != Qt::Key_Select) {
return false;
}
} else {
return false;
}
bool checked = index.model()->data(index, Qt::DisplayRole).toBool();
return model->setData(index, !checked, Qt::EditRole);
}
这篇关于Qt QTableView如何只有一个复选框列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!