У меня есть простой класс на основе QTreeWidget. В некоторых случаях (при обновлении значения одного из столбцов) мне нужно его перекрасить. У меня есть функция, которая вызывается, когда мне нужно обновить виджет:
void TreeWidget::updated()
{
/* some actions with cells */
/* here need to repaint widget */
this->update();
/* also I'm tried this->repaint(); */
}
Но линия this->update(); (или this->repaint();) результатов не дала. Виджет перерисовывается только при нажатии на него.
Итак, как мне перекрасить свой виджет?
@eyllanesc, это работа! Спасибо!





Классы, которые наследуются от QAbstractScrollArea как QTreeWidget, имеют viewport(), который является виджетом, который необходимо обновить, поэтому в вашем случае решение:
viewport()->update();
Если вы хотите вызвать обновление из другого потока, вы можете использовать QMetaObject :: invokeMethod ():
QMetaObject::invokeMethod(viewport(), "update", Qt::QueuedConnection)
Это решение:
viewport()->update();
Мне интересно: чем ваше решение отличается от моего? :-)
Я узнал одну интересную вещь. Как оказалось, обновлять виджеты в Qt можно только из основного потока. Моя функция updated() была вызвана другим потоком, поэтому this->update() не работал. Однако все слоты в Qt выполняются только в основном потоке, откуда бы они ни вызывались. В этом случае правильным решением будет завернуть this->update() внутрь слота. Нравится:
TreeWidget::TreeWidget()
{
/* ... */
connect(this, SIGNAL(signal_update()), this, SLOT(slot_update()));
/* ... */
}
void TreeWidget::updated()
{
/* some actions with cells */
emit signal_update();
}
void TreeWidget::slot_update()
{
this->update();
}
Да, это менее красивое решение, чем this->viewport()->update(), но более правильное.
Если вы хотите выполнить его из другого потока, нет необходимости создавать сигнал, вам просто нужно использовать QMetaObject::invokeMethod(), как я упоминал в своем обновленном решении :-)
попробуйте с
viewport()->update();