我有一个QTableWidget,在不同的列上有不同类型的单元格小部件,有多个列显示复选框。
我想将QCheckBox的stateChanged信号连接到我的一个插槽,以便我可以在我的模型中相应地设置数据。
问题是当用户更改QCheckBox状态时,QTableWidget的当前行不一定会改变。
所以我考虑继承QCheckBox并添加用于保存行和列信息的变量。这是一个好方法吗?当我使用UI元素存储数据时,有什么问题(如果有的话)。
答案 0 :(得分:1)
这只是我想到的第一个想法。 我将所有的QCheckBox连接到同一个插槽(通过它们循环或在创建的那一刻)然后当插槽被执行时,我将得到它的调用者,它将是QCheckBox,我将得到它的父节点,它将是它的单元格&# 39; s in。
答案 1 :(得分:1)
我会在不增加额外课程的情况下这样做,而是将小部件的行和列存储在地图中:
class YourWidgetWithTable
{
public:
void foo()
{
//when you add cell widgets, do something like this:
QCheckBox * b = new QCheckBox();
tableWidget->setCellWidget(row, col, b);
_widgetCells[b] = QPoint(row, col);
connect(b, &QCheckBox::stateChanged, this, &YourWidgetWithTable::checkboxStateChanged);
//if for whatever reason you are removing a checkbox from the table, don't forget to remove it from the map as well.
}
public slots:
void checkboxStateChanged(int)
{
//in your slot, you can now get the row and col like so:
QCheckBox * box = dynamic_cast<QCheckBox*>(sender());
QPoint rowAndColumn = _widgetCells[box];
}
private:
QMap<QCheckBox*, QPoint> _widgetCells; //QPoint for storing the row and column
}
当然,您可以在不使用dynamic_cast
的情况下使用QObject*
指针执行相同操作。
答案 2 :(得分:1)
如果您坚持使用setCellWidget并且使用C ++ 11而不是使用lambda表达式进行连接。这样就可以了:
void MainWindow::setupCheckboxes() {
for (int i=1; i<=tableWidget->rowCount(); ++i) {
QCheckBox *checkbox = new QCheckBox();
... // setup checkbox
tableWidget->setCellWidget(i, kSomeColumnIndex, checkbox);
connect(checkbox, &QAbstractButton::toggled, [this, i](bool checked) {
this->stateOfRowHasChanged(i, checked);
});
}
}
void MainWindow::stateOfRowHasChanged(int row, bool checked) {
// update item model
QTableWidgetItem *item = tableWidget->item(row, kSomeColumnIndex);
item->setData(Qt::CheckStateRole, checked?Qt::Checked:Qt::Unchecked);
...
}
如果您不喜欢lambdas,请将复选框连接到此插槽:
void MainWindow::checkboxStateHasChenged(bool checked) {
QCheckBox *checkbox = qobject_cast<QCheckBox *>(sender());
if (checkbox) {
QTableWidgetItem *item = tableWidget->itemAt(tableWidget->mapFrom(checkbox, QPos()));
if (item) {
item->setData(Qt::CheckStateRole, checked?Qt::Checked:Qt::Unchecked);
...
}
}
}
答案 3 :(得分:0)
你做的事情非常糟糕。你没有显示代码所以很难说出什么是错误的(我只是怀疑)。
无论如何这是MVC模式。因此,如果您想观察状态变化,您必须观察数据模型的变化。您应该连接到dataChanged(还有其他更方便的信号QTableWidget::cellChanged)。数据可以model()或更多。
使用数据模型更重要的是,您可以在表格视图中设置检查默认复选框(您不必手动添加它们)。
代码示例:
QTableWidgetItem *item = new QTableWidgetItem(tr("Somthing"));
item->setFlags(Qt::ItemIsUserCheckable|Qt::ItemIsEnabled|Qt::ItemNeverHasChildren);
tableWidget->setItem(row, column, item); // or add or whatever to add this item to widget and its model
connect(tableWidget->model(), SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector<int>)),
this, SLOT(dataWasChanged(QModelIndex,QModelIndex,QVector<int>)));
// or
connect(tableWidget, SIGNAL(cellChanged(int, int)),
this, SLOT(cellWasChanged(int, int)));
答案 4 :(得分:0)
QPoint pos = tableWidget->mapFromGlobal(QCursor::pos());
QTableWidgetItem* item = tableWidget->item(tableWidget->indexAt(pos).row() - 1 , 0);
获得该项目后,您将获得该职位。