I need to know when the verticalScrollBar of my QTableWidget is being shown.
I am currently using the following instruction:
Header:
#ifndef MYCLASS_H
#define MYCLASS_H
#include <QDebug>
#include <QWidget>
#include <QScrollBar>
namespace Ui {
class MyClass;
}
class MyClass: public QWidget
{
Q_OBJECT
public:
explicit MyClass(QWidget *parent = 0);
~MyClass();
private:
void populateTable(QVector<QString> content);
private:
Ui::MyClass *ui;
};
#endif // MYCLASS_H
Populate table function:
void MyClass::populateTable(QVector<QString> content)
{
while( ui->myTableWidget->rowCount() > 0 )
{
ui->myTableWidget->removeRow(0);
}
QTableWidgetItem* item;
for (int row = 0; row < content.length(); ++row)
{
ui->myTableWidget->insertRow(row);
item = new QTableWidgetItem( QString::number(row) );
item->setTextAlignment(Qt::AlignCenter);
ui->myTableWidget->setItem(row, 0, item);
item = new QTableWidgetItem( content.at(row) );
item->setTextAlignment(Qt::AlignCenter);
ui->myTableWidget->setItem(row, 1, item);
}
qDebug() << "This : " << this->isVisible();
qDebug() << "QTableWidget : " << ui->myTableWidget->isVisible();
qDebug() << "VerticalScrollBar : " << ui->myTableWidget->verticalScrollBar()->isVisible(); // <-HERE
}
Output:
// Called from the constructor
This : false
QTableWidget : false
VerticalScrollBar : false
// Called by a button pressed
This : true
QTableWidget : true
VerticalScrollBar : true
This : true
QTableWidget : true
VerticalScrollBar : false
But it returns a wrong value. When the ScrollBar is visible it returns false and when it is not visible it returns true. Note: myTableWidget (QTableWidget) is always visible.
Is there any other way that I can do this?
I'm using Qt version 5.3.2
In general the code you are using is supposed to work - checked on Qt 5.3.0.
However, you must be sure that when you are making the call the
QTableWidgetitself is visible.For example if you make the call inside the
MainWindowconstructor you will certainly get afalseanswer. Only after the form is shown the call to isVisible() on particular scrollbar would return the correct value.EDIT:
With your code pasted I was able to reproduce the issue. I needed to go through the Qt code a bit to see whats going on. Basically it turns out that for
QTableViewwhich is parent class ofQTableWidgetscroll bar values are updated viaupdateGeometries(do not confuse it with the regularupdateGeometrythe one I'm mentioning isprotected). Internally this method is called either directly or the event is processed through the event loop. In short, it depends on whether you add columns or rows.In your example, if you
insertColumninstead ofinsertRow(and switch the arguments insetItem) after checking the visibility ofhorizontalScrollBaryou will get the proper result right away.I could confirm this by subclassing the
QTableWidgetand overridingeventmethod. It shows that when adding columns following events are executed:MetaCall(invoke call) andLayoutRequest. On the other hand, when adding rows first event passed isTimer.I'm not Qt implementer so I'm not sure what is the purpose the difference. However, this info helps solving your problem in a more elegant way.
You can implement
MyTableWidgetwhich overrides theeventmethod.However, such event might get called in other situations not only when the view needs to be updated due to model data updates.
Another solution would be to avoid overriding the
eventmethod but creating your own method to trigger the required updates. For example:This would call directly
updateGeometrieswhich recalculates scrollbar min/max values and perform a directeventmethod call forLayoutRequest(without processing through eventloop). Which if I'm correct indirectly updates scrollbar visibility.Calling this method before checking the visibility should also fix your problem.