【问题标题】:Selecting QComboBox in QTableWidget在 QTableWidget 中选择 QComboBox
【发布时间】:2010-11-22 20:36:09
【问题描述】:

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()

要取回组合框的副本并获取新的选择。
但我无法获得行/列。
选择或更改嵌入项时,何时不会发出表格克萨克斯信号,并且没有设置Currentrow()/ currentColumn()。

【问题讨论】:

    标签: c++ qt qt4 qtablewidget qcombobox


    【解决方案1】:

    不需要信号映射器...创建组合框后,您只需为其添加两个自定义属性:

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

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

    现在通过询问属性,您可以返回您的行/列:

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

    【讨论】:

    • 如果某些行在运行时被删除了怎么办?如何更新项目的属性?
    • this thread得到了我的问题的答案
    【解决方案2】:

    刚遇到同样的问题,这就是我解决的方法。我使用 QPoint,这是一种比 QString 更简洁的方式来保存 x-y 值。希望这会有所帮助。

    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 感谢您指出这一点。我的回复已经过去了很长时间,我无法回答你的问题。祝你有美好的一天。
    【解决方案3】:

    扩大游吟诗人的answer

    以下是对 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,然后将更改的函数删除。

    此解决方案的缺点是您会丢失 currentIndexChanged 发出的值,但您可以从 ::changed 查询 QComboBox 的索引。

    【讨论】:

    • connect(signalMapper, SIGNAL(mapped(const QString &)),this, SLOT(changed(const QString &)));
    • @J.Chomel 抱歉,我看不出您的评论与我的第一个代码块的最后一行有何不同。你能详细说明一下吗?
    • @Bill 谢谢...它帮助了我并且能够解决我的问题。
    【解决方案4】:

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

    【讨论】:

      猜你喜欢
      • 2017-02-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-15
      • 2020-06-26
      • 2017-02-27
      相关资源
      最近更新 更多