QTableWidget、Cellwidget、QLabel

QTableWidget, Cellwidget, QLabel

我创建了一个 QTableWidget。一些单元格填充有单元格小部件(修改后的 QLabel,发送点击信号)。 现在,我想对点击这个标签做出反应。我添加了一些调试功能。

单击空单元格会将正确的行和列写入控制台。 单击标签被识别为单击,但行和列错误(使用之前的单元格数据)。

问题:点击标签时如何获得正确的行和列。

问候和感谢,迈克尔

MtTimeTable::MtTimeTable( QWidget* parent )
    : QTableWidget { parent }, mIdArray { MtIdArray() },
      mDate { QDate::currentDate() }
{
    this->fillLesssonWidgets();

    connect( this, &MtTimeTable::cellClicked,
             this, &MtTimeTable::slotCellActivated );
}

void MtTimeTable::fillLessonWidgets()
{
    MtLessonVec lessonVec { true }; // Data to show, loaded from file

    auto cit { lessonVec.begin() };
    while( cit != lessonVec.end() ) {
        // Class MtLessonWidget derived from QLabel
        MtLessonWidget* lessonWidget { new MtLessonWidget };
        lessonWidget->setLesson( *cit );
        // Using member functions of MtLessonwidget, working correct
        this->setCellWidget( lessonWidget->startingRow(), 
                             lessonWidget->startingCol(), 
                             lessonWidget );

        }

        connect( lessonWidget, &MtLessonWidget::sigClicked,
                 this, &MtTimeTable::slotLessonWidgetClicked );

        ++cit;
    }

}

我已尝试将代码减少到最少。

void MtTimeTable::slotLessonWidgetClicked()
 {        
    std::cerr << "Table Cell: [" << this->currentRow() << "," 
          << this->currentColumn() << "]" << std::endl;
}

根据 docs:

int QTableWidget::currentColumn() const

Returns the column of the current item.

int QTableWidget::currentRow() const

Returns the row of the current item.

也就是item的位置,它指的是一个QTableWidgetItem,但是如果我们用setCellWidget没有创建一个item,所以那些位置不合适,我们必须寻找其他方法来获取与小部件关联的行和列。

一种方法是使用 indexAt() 方法,该方法 returns 与单元格关联的 QModelIndex 给定其相对于 QTableWidgetviewport() 的位置, 那就是应该使用的那个:

void MtTimeTable::slotLessonWidgetClicked(){
    auto lbl = qobject_cast<MtLessonWidget *>(sender());
    if(lbl){
       auto ix = indexAt(lbl->pos());
       qDebug()<<"Table Cell: [" <<ix.row()<< ","  <<ix.column()<< "]";
    }
}

完整示例:

#include <QApplication>
#include <QLabel>
#include <QTableWidget>
#include <QDebug>

class CustomLabel: public QLabel{
    Q_OBJECT
protected:
    void mousePressEvent(QMouseEvent *){
        emit clicked();
    }
signals:
    void clicked();
};

class TableWidget: public QTableWidget{
    Q_OBJECT
public:
    TableWidget(QWidget* parent=Q_NULLPTR):QTableWidget(parent){
        setRowCount(10);
        setColumnCount(10);
        for(int i=0; i<rowCount(); i++){
            for(int j=0; j<columnCount(); j++){
                auto lbl = new CustomLabel;
                setCellWidget(i, j, lbl);
                connect(lbl, &CustomLabel::clicked, this, &TableWidget::onClicked);
            }
        }
    }
private slots:
    void onClicked(){
        auto lbl = qobject_cast<CustomLabel *>(sender());
        if(lbl){
           auto ix = indexAt(lbl->pos());
           qDebug()<<"Table Cell: [" <<ix.row()<< ","  <<ix.column()<< "]";
        }
    }
};

#include "main.moc"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    TableWidget w;
    w.show();

    return a.exec();
}

下面link我展示完整example.