У меня проблема: вызов 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, но этого не происходит. Что я делаю неправильно?
Я также проверил и получил тот же результат (не работает):
- обновление (прямо)
- перекрасить, перекрасить (прямо)
- обновитьгеометрию()
- 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();
};
CONFIG += c++11
и объявите обработчик события какvoid paintEvent(QPaintEvent*) override;
. Убедитесь, что он все еще компилируется - если это не так, вы не переопределяете функцию, которую вы считаете :) - person Kuba hasn't forgotten Monica   schedule 11.04.2014