在QTableWidget中选择QComboBox

17

在QTableWidget的每一行中,有一个单元格包含一个下拉框。

for (each row in table ... ) {
   QComboBox* combo = new QComboBox();      
   table->setCellWidget(row,col,combo);             
   combo->setCurrentIndex(node.type());                 
   connect(combo, SIGNAL(currentIndexChanged(int)),this, SLOT(changed(int)));
   ....
}

在处理函数::changed(int index)中,我有

QComboBox* combo=(QComboBox*)table->cellWidget(_row,_col);  
combo->currentIndex()

为了获取下拉框的副本并获得新的选择。
但是我无法获得行/列。
当选择或更改嵌入项目时,没有任何表格cellXXXX信号被发出,并且currentRow()/currentColumn()未设置。

4个回答

13

无需使用信号映射器...当创建组合框时,您可以简单地向其添加两个自定义属性:

combo->setProperty("row", (int) nRow);
combo->setProperty("col", (int) nCol);

在处理函数中,您可以获得信号的发送者(即您的组合框)的指针。

现在通过请求属性,您可以找回您的行/列:

int nRow = sender()->property("row").toInt();
int nCol = sender()->property("col").toInt();

如果在运行时删除了某些行,该怎么办?我如何更新项目的属性? - George
这个帖子中得到了我问题的答案。 - George

9

在 Troubadour 的 答案 的基础上进行扩展:

这是对 QSignalMapper 文档的修改,以适应您的情况:

 QSignalMapper* signalMapper = new QSignalMapper(this);

 for (each row in table) {
     QComboBox* combo = new QComboBox();
     table->setCellWidget(row,col,combo);                         
     combo->setCurrentIndex(node.type()); 
     connect(combo, SIGNAL(currentIndexChanged(int)), signalMapper, SLOT(map()));
     signalMapper->setMapping(combo, QString("%1-%2").arg(row).arg(col));
 }

 connect(signalMapper, SIGNAL(mapped(const QString &)),
         this, SLOT(changed(const QString &)));

在处理函数::changed(QString position)中:
 QStringList coordinates = position.split("-");
 int row = coordinates[0].toInt();
 int col = coordinates[1].toInt();
 QComboBox* combo=(QComboBox*)table->cellWidget(row, col);  
 combo->currentIndex()

请注意,使用QString传递此信息的方式比较笨拙。更好的选择是传递一个新的QModelIndex,并在changed函数中进行删除。
这种解决方案的缺点是你会失去currentIndexChanged发出的值,但你可以从::changed查询QComboBox的索引。

1
connect(signalMapper, SIGNAL(mapped(const QString &)),this, SLOT(changed(const QString &))); 连接(signalMapper,SIGNAL(mapped(const QString &)),this,SLOT(changed(const QString &))); - Martin Beckett
@J.Chomel 抱歉,我不明白你的评论与我第一个代码块的最后一行有何不同。你能详细说明一下吗? - Bill
@ Bill 谢谢...它帮了我,成功解决了我的问题。 - Omkar

2

我认为您需要看一下QSignalMapper。这听起来像是该类的典型用例,即您有一组对象,在每个对象上都连接到相同的信号,但想知道哪个对象发出了信号。


-1

刚遇到了同样的问题,这是我解决的方法。我使用QPoint来保存x-y值,这比使用QString更加简洁。希望对你有帮助。

classConstructor() {
    //some cool stuffs here
    tableVariationItemsSignalMapper = new QSignalMapper(this);
}

void ToolboxFrameClient::myRowAdder(QString price) {
    QLineEdit *lePrice;
    int index;
    //
    index = ui->table->rowCount();
    ui->table->insertRow(index);
    //
    lePrice = new QLineEdit(price);
    connect(lePrice, SIGNAL(editingFinished()), tableVariationItemsSignalMapper, SLOT(map()));
    tableVariationItemsSignalMapper->setMapping(lePrice, (QObject*)(new QPoint(0, index)));
    // final connector to various functions able to catch map
    connect(tableVariationItemsSignalMapper, SIGNAL(mapped(QObject*)),
             this, SLOT(on_tableVariationCellChanged(QObject*)));
}

void ToolboxFrameClient::on_tableVariationCellChanged(QObject* coords) {
    QPoint *cellPosition;
    //
    cellPosition = (QPoint*)coords;
}

我认为你在 QPoint 对象中存在内存泄漏,为什么要使用 new?此外,在这种情况下,您实际上并不需要 QPoint 提供的工具,因此我不会从中受益太多。 - ymoreau
@ymoreau 感谢您指出这一点。自从我回复以来已经过了很长时间,我无法回答您的问题。祝您有美好的一天。 - Daniele Vrut

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接