如何与复选框操作进行交互? (带有 QStandardItemModel 的 QTableView)
Posted
技术标签:
【中文标题】如何与复选框操作进行交互? (带有 QStandardItemModel 的 QTableView)【英文标题】:How to interact with checkbox actions ? (QTableView with QStandardItemModel) 【发布时间】:2010-05-07 00:27:56 【问题描述】:我正在使用 QTableView 和 QStandardItemModel 来显示一些数据。
每一行有一列有一个复选框,这个复选框是由setItem插入的,代码如下:
int rowNum;
QStandardItemModel *tableModel;
QStandardItem* __tmpItem = new QStandardItem();
__tmpItem->setCheckable(true);
__tmpItem->setCheckState(Qt::Unchecked);
tableModel->setItem(rowNum,0,__tmpItem);
现在我想与复选框进行交互。如果用户更改复选框的状态(从选中变为未选中,反之亦然),我想在相应的数据行上做一些事情。
我知道我可以使用信号槽来捕捉复选框的变化,但是由于数据行很多,我不想将每一行一一连接。
是否有更有效地与检查操作交互?谢谢:)
【问题讨论】:
【参考方案1】:我不处理 QTableView+QStandardItemModel,但下面的示例可能会对您有所帮助:
1)。 table.h 文件:
#ifndef TABLE__H
#define TABLE__H
#include <QtGui>
class ItemDelegate : public QItemDelegate
public:
ItemDelegate(QObject *parent = 0)
: QItemDelegate(parent)
virtual void drawCheck(QPainter *painter, const QStyleOptionViewItem &option,
const QRect &, Qt::CheckState state) const
const int textMargin = QApplication::style()->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1;
QRect checkRect = QStyle::alignedRect(option.direction, Qt::AlignCenter,
check(option, option.rect, Qt::Checked).size(),
QRect(option.rect.x() + textMargin, option.rect.y(),
option.rect.width() - (textMargin * 2), option.rect.height()));
QItemDelegate::drawCheck(painter, option, checkRect, state);
virtual bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option,
const QModelIndex &index)
Q_ASSERT(event);
Q_ASSERT(model);
// make sure that the item is checkable
Qt::ItemFlags flags = model->flags(index);
if (!(flags & Qt::ItemIsUserCheckable) || !(flags & Qt::ItemIsEnabled))
return false;
// make sure that we have a check state
QVariant value = index.data(Qt::CheckStateRole);
if (!value.isValid())
return false;
// make sure that we have the right event type
if (event->type() == QEvent::MouseButtonRelease)
const int textMargin = QApplication::style()->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1;
QRect checkRect = QStyle::alignedRect(option.direction, Qt::AlignCenter,
check(option, option.rect, Qt::Checked).size(),
QRect(option.rect.x() + textMargin, option.rect.y(),
option.rect.width() - (2 * textMargin), option.rect.height()));
if (!checkRect.contains(static_cast<QMouseEvent*>(event)->pos()))
return false;
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;
Qt::CheckState state = (static_cast<Qt::CheckState>(value.toInt()) == Qt::Checked
? Qt::Unchecked : Qt::Checked);
QMessageBox::information(0,
QString((state == Qt::Checked) ? "Qt::Checked" : "Qt::Unchecked"),
QString("[%1/%2]").arg(index.row()).arg(index.column()));
return model->setData(index, state, Qt::CheckStateRole);
virtual void drawFocus(QPainter *painter, const QStyleOptionViewItem &option, const QRect &rect) const
QItemDelegate::drawFocus(painter, option, option.rect);
;
static int ROWS = 3;
static int COLS = 1;
class Table : public QTableWidget
Q_OBJECT
public:
Table(QWidget *parent = 0)
: QTableWidget(ROWS, COLS, parent)
setItemDelegate(new ItemDelegate(this));
QTableWidgetItem *item = 0;
for (int i=0; i<rowCount(); ++i)
for (int j=0; j<columnCount(); ++j)
setItem(i, j, item = new QTableWidgetItem);
item->setFlags(Qt::ItemIsEnabled|Qt::ItemIsUserCheckable);
item->setCheckState((i+j) % 2 == 0 ? Qt::Checked : Qt::Unchecked);
;
#endif
2)。 main.cpp 文件:
#include <QApplication>
#include "table.h"
int main(int argc, char **argv)
QApplication a(argc, argv);
Table w;
w.show();
return a.exec();
祝你好运。
PS:这里是原文text。
【讨论】:
非常感谢!!!它确实有效 :D~\n 但是,通过这种方式,tableview 中的每个元素都将包含一个复选框,如果我只是希望复选框出现在某些特定列中,我需要修改哪一部分??再次感谢您,这个例子真的很有帮助:D @Claire Huang 您可以编辑 Table 类以在一个选定的列中获得能力设置复选框,例如:for (...) for (...) setItem (...); if (j == mySelectedColumn) item->setFlags(Qt::ItemIsEnabled|Qt::ItemIsUserCheckable);否则 item->setFlags(Qt::ItemIsEnabled); ...等我认为是这样的。 :)【参考方案2】:处理点击事件,你会得到modelindex,获取数据和修改一样
如果要插入多个文本或图标,则需要为列表视图设置委托
【讨论】:
非常感谢,不使用 QItemDelegate 也能正常工作!!! :D 我只需要添加一个插槽就可以了,一切正常,太棒了!!【参考方案3】:这是 mosg 建议的示例的另一个类似想法,使用 QStyleItemDelegate 代替。 http://developer.qt.nokia.com/faq/answer/how_can_i_align_the_checkboxes_in_a_view
【讨论】:
【参考方案4】:在点击的插槽和index.data(Qt::CheckStateRole)
上使用:
void MainWindow::on_tableView_clicked(const QModelIndex &index)
if(index.column() == 2)
if(index.data(Qt::CheckStateRole) == Qt::Checked)
//your code
else if(index.data(Qt::CheckStateRole) == Qt::Unchecked)
//your code
//get other infos
QVariant value = index.sibling(index.row(),0).data();
QString selectedMessageName = value.toString();
【讨论】:
以上是关于如何与复选框操作进行交互? (带有 QStandardItemModel 的 QTableView)的主要内容,如果未能解决你的问题,请参考以下文章
如何在管理面板中为多行添加带有批量操作(如 CRUD)的复选框 [重复]
如何在 SwiftUI ForEach 内容中将多个按钮操作分开?
在 APEX 5.1 的交互式报告中选中相关复选框时如何启用选择列表
当 UIPopoverController 在屏幕上时,无法与带有 UIPopoverController 的 UISearchBar 进行交互