I'm developing a timeline editor containing tracks represented by QLabels
in a QScrollArea
.
First there's a track by default, and we can add and remove tracks dynamically.
I'm having issue with the fact that when there are a few tracks left (3) and I remove one of them, the painting is broken, please see the gif below:
I've tried :
qApp->processEvents()
update()
show()
style()->unpolish(); style()->polish();
and I applied those methods to all graphical elements implied in this context.
Here is my code description :
EditCueTimelineWidget
class is the global widget shown is the image.ui->TimelineEditScrollArea
is theQScrollArea
.ui->scrollAreaWidgetContents
is thescrollArea
's content widget._trackLabelList
is aQVector
ofTrackLabel
._subTrackLabelList
(for eachTrackLabel
) is aQVector
ofSubTrackLabel
.TrackLabel
andSubTrackLabel
have a_label
member which is aVerticalLabel
(which shows the name vertically) and a_strip
member which is aQLabel
with orange or yellow color (showing which track or subtrack is currently selected).
Here's the code
void EditCueTimelineWidget::refreshWidget()
{
qApp->processEvents();
ui->label->refreshTimemarks();
for(auto l :qAsConst(_trackLabelList))
{
l->recenterWidgets();
l->update();
l->show();
}
style()->unpolish(ui->scrollAreaWidgetContents);
style()->polish(ui->scrollAreaWidgetContents);
style()->unpolish(ui->TimelineEditScrollArea);
style()->polish(ui->TimelineEditScrollArea);
style()->unpolish(this);
style()->polish(this);
ui->scrollAreaWidgetContents->update();
ui->TimelineEditScrollArea->update();
update();
ui->scrollAreaWidgetContents->show();
ui->TimelineEditScrollArea->show();
show();
ui->nbTracksLabel->setText(QString::number(_trackLabelList.size())+tr(" Tracks"));
qApp->processEvents();
}
void TrackLabel::recenterWidgets()
{
_label->setFixedSize(50,height());
_label->move(40,0);
_strip->setFixedSize(15, height());
_strip->move(1,1);
int nbSub = _subTrackLabelList.size();
for(int k = 0; k <nbSub ; k++)
{
SubTrackLabel* l = _subTrackLabelList.at(k);
int h = height()/nbSub;
int posY = k * h;
if(k != (nbSub -1))
l->setFixedSize(width() - 100, h);
else
l->setFixedSize(width() - 100, height() - posY);
l->move(100,posY);
l->recenterWidgets();
l->update();
l->show();
}
style()->unpolish(_label);
style()->polish(_label);
style()->unpolish(_strip);
style()->polish(_strip);
style()->unpolish(this);
style()->polish(this);
_label->update();
_strip->update();
_label->show();
_strip->show();
}
void SubTrackLabel::recenterWidgets()
{
_label->setFixedSize(35,height());
_label->move(20,0);
_strip->setFixedSize(12, height());
_strip->move(1,1);
style()->unpolish(_label);
style()->polish(_label);
style()->unpolish(_strip);
style()->polish(_strip);
style()->unpolish(this);
style()->polish(this);
_label->update();
_strip->update();
_label->show();
_strip->show();
}
Note that I have a resizing eventFilter
on EditCueTimelineWidget
, and when I resize the application manually, I get the result expected: the two last tracks take all the space and are correctly shown :
bool EditCueTimelineWidget::eventFilter(QObject *, QEvent *event)
{
if (event->type() == QEvent::Resize)
{
refreshWidget();
return true;
}
return false;
}
Also note that in TrackLabel
constructor, I have this :
setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Preferred);
setMinimumHeight(300);
What method should I call, or should I change call order of the methods I'm already using, in order to get the result I need?