Qt 5.2 вызов QTableWidget :: update не приводит к QTableWidget :: paintEvent

У меня проблема: вызов QTableWidget :: update не приводит к QTableWidget :: paintEvent.

Краткое описание:
— QTableWidgetEx — класс, производный от QTableWidget, с paintEvent перекрываться.
— Некоторый код, создающий QTableWidgetEx и два пункта меню ‘call_update’ и ‘check_paint_cnt’

Последовательность тестирования

  • Нажмите «check_paint_cnt» — строка состояния показывает «paint_cnt = 1» (так
    paintEvent является называется)
  • Нажмите ‘call_update’
  • Снова нажмите «check_paint_cnt» — в строке состояния отображается «paint_cnt = 1», но
    должно быть 2 … (не вызывать paintEvent)
  • Изменение размера окна увеличивает paint_cnt, поэтому функция успешно переопределяется и иногда вызывается, но не с обновлением или перерисовкой.

(Небольшое тестовое приложение — ниже.
Тестовый проект как пустой проект Qt, созданный мастером (Qt 5.2): http://s000.tinyupload.com/index.php?file_id=57865294773039719910 — полный исходный код.)

Я протестировал «перекрасить» вместо «обновления» — он дает тот же результат.

Вопрос:
Документация говорит, что QTableWidget :: update должен запускать QTableWidget :: paintEvent, но это не так
Что я делаю неправильно?

Я тоже проверял и получаю такой же результат (не работает):

  • обновление (Прямоугольник)
  • перекрасить, перекрасить (прямоугольник)
  • updateGeometry ()
  • w-> resize (w-> width (), w-> height ());

Хороший обходной путь:

inline void wa_widget_update(QWidget* w)
{
if(auto a = dynamic_cast<QAbstractScrollArea*>(w))
a->viewport()->update();
else
w->update();
};

вместо w-> update () используйте wa_widget_update (w). Немного некрасиво, но работает.
Сообщил об этой ошибке в проект qt:
Ссылка на багтрекер

Полные источники:

#--------------------------------------------------
# Qt_Update_Test.pro contents
#--------------------------------------------------
QT             += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET         = Qt_Update_Test
TEMPLATE       = app
SOURCES        += main.cpp
HEADERS        += main.h

//--------------------------------------------------
// main.h contents
//--------------------------------------------------

#ifndef MAIN_H
#define MAIN_H

#include <QApplication>
#include <QMainWindow>
#include <QTableWidget>
#include <QPaintEvent>
#include <QStatusBar>
#include <QMenuBar>

extern int paints_cnt;    // Global variable - paintEvent calls counter

class QTableWidgetEx : public QTableWidget
{
Q_OBJECT
public:
inline explicit QTableWidgetEx(QWidget *parent = 0) : QTableWidget(parent) {};
protected:
virtual void paintEvent(QPaintEvent* e) override;
};class MainWindow : public QMainWindow
{
Q_OBJECT
public:
QTableWidgetEx*        table_widget_ex;
QMenuBar*              menuBar;
QStatusBar*            statusBar;

explicit MainWindow(QWidget *parent = 0);
inline ~MainWindow(){};
protected slots:
void on_call_update();
void on_check_paint_cnt();
};

#endif

//--------------------------------------------------
// main.cpp contents
//--------------------------------------------------

#include "main.h"int paints_cnt = 0;    // Global variable - paintEvent calls counter

void QTableWidgetEx::paintEvent(QPaintEvent* e)
{
++paints_cnt;
QTableWidget::paintEvent(e);
}

void MainWindow::on_call_update()
{
table_widget_ex->update();
};

void MainWindow::on_check_paint_cnt()
{
statusBar->showMessage("paints_cnt = " + QString::number(paints_cnt));
};

// Below - Layout code, signal-slots, entry point, etc...
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
{
resize(400, 300);

menuBar = new QMenuBar(this);
setMenuBar(menuBar);

table_widget_ex = new QTableWidgetEx(this);
table_widget_ex->setUpdatesEnabled(true);
setCentralWidget(table_widget_ex);

statusBar = new QStatusBar(this);
setStatusBar(statusBar);

auto call_update = new QAction("call_update", this);
connect(call_update, SIGNAL(triggered()), this, SLOT(on_call_update()));
menuBar->addAction(call_update);

auto check_paint_cnt = new QAction("check_paint_cnt", this);
connect(check_paint_cnt, SIGNAL(triggered()), this, SLOT(on_check_paint_cnt()));
menuBar->addAction(check_paint_cnt);
};

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
};

1

Решение

QTableWidget происходит от QAbstractScrollArea и использует виджет видового экрана. Если вы вызовете метод update () виджета области просмотра, будет запущен paintEvent:

void MainWindow::on_call_update()
{
table_widget_ex->viewport()->update();
}

Более подробная информация также на: update () или repaint () не могут вызвать paintEvent ()

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]