0
votes

I've created a QTableWidget. Some of the cells are filled with a cell widget (a modified QLabel, sending a clicked signal). Now, I want to react on a click on this label. I add some debugging functions.

Clicking on an empty cell writes the correct row and column to console. Clicking on the label is reckognized as a click, but with the wrong row and column (the previous cell data is used).

Question: How can I get the correct row and column for clicking on the label.

Greetings and thanks, Michael

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;
    }

}

I've tried to reduce the code to a minimum.

void MtTimeTable::slotLessonWidgetClicked()
 {        
    std::cerr << "Table Cell: [" << this->currentRow() << "," 
          << this->currentColumn() << "]" << std::endl;
}
1
Maybe your bug is in the modified cell widget.drescherjm
It's just a simple class derived from QLabel, adding only a protected function for a mouse press event. The signal is emitted correct.macnet65
The QTableWidget cell with the widget in it does not react on a mouse click.macnet65
You could show your code to see what the problem is.eyllanesc
You could show the implementation of slotLessonWidgetClicked. :Peyllanesc

1 Answers

1
votes

According to the docs:

int QTableWidget::currentColumn() const

Returns the column of the current item.

int QTableWidget::currentRow() const

Returns the row of the current item.

That is, it is the position of the item, and it refers to a QTableWidgetItem, but if we use setCellWidget an item is not created, so those positions are not suitable, we must look for another means to obtain the row and column associated with the widget.

One way is to use the indexAt() method that returns a QModelIndex associated with the cell given its position relative to the viewport() of QTableWidget, and that is the one that should be used:

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

Complete Example:

#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();
}

In the following link I show the complete example.