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
给定其相对于 QTableWidget
的 viewport()
的位置, 那就是应该使用的那个:
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.
我创建了一个 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
给定其相对于 QTableWidget
的 viewport()
的位置, 那就是应该使用的那个:
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.