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
QTableWidget
itself is visible.For example if you make the call inside the
MainWindow
constructor you will certainly get afalse
answer. 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
QTableView
which is parent class ofQTableWidget
scroll bar values are updated viaupdateGeometries
(do not confuse it with the regularupdateGeometry
the 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
insertColumn
instead ofinsertRow
(and switch the arguments insetItem
) after checking the visibility ofhorizontalScrollBar
you will get the proper result right away.I could confirm this by subclassing the
QTableWidget
and overridingevent
method. 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
MyTableWidget
which overrides theevent
method.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
event
method but creating your own method to trigger the required updates. For example:This would call directly
updateGeometries
which recalculates scrollbar min/max values and perform a directevent
method 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.