3

I have a widget class subclass of QMainWindow, and it has a central widget(QWidget), and in the overriden paintEvent function, can I create an instance of QPainter on this central widget? Code like:

void MyMainWindow::paintEvent(QEvent *event)
{
    QPainter painter(_theCentralWidget);
    //drawing...
    return QMainWindow::paintEvent(event);
}

I don't want to create a new c++ class subclass of QWidget and override its paintEvent function and then replace the original central widget with this new one... (I did like above but an error occured saying the painter is not active...)

tmj
  • 1,143
  • 3
  • 11
  • 15
  • Possible duplicate of: http://stackoverflow.com/questions/11034838/paint-draw-on-top-of-docked-widgets-in-qdodckwidget – cmannett85 Jun 21 '12 at 14:19

3 Answers3

4

Well. If you really, really, really don't want to sub-class the central widget, you can install a event filter to it and handle the paint event for it.

http://qt-project.org/doc/qt-4.8/qobject.html#installEventFilter

Stephen Chu
  • 12,724
  • 1
  • 35
  • 46
3

You can use C++11 lambdas to solve this problem. Create a new generic "event for anything" QObject that passes its filtering through a lambda you specify. Then add this generic object to your display widget with the desired logic. For example:

generic-qevent-filter.hpp:

#pragma once

class GenericQEventFilter : public QObject
{
  Q_OBJECT

public:
  GenericQEventFilter(QObject *parent, std::function<bool (QObject *obj, QEvent *event)> event_filter_f);
  std::function<bool (QObject *obj, QEvent *event)> event_filter_f;

protected:
  bool eventFilter(QObject *obj, QEvent *event);

};

generic-qevent-filter.cpp:

#include "generic-qevent-filter.hpp"

GenericQEventFilter::GenericQEventFilter(QObject *parent, 
                     std::function<bool (QObject *obj, QEvent *event)> event_filter_f)
  : QObject(parent), event_filter_f(event_filter_f)
{
}


bool GenericQEventFilter::eventFilter(QObject *obj, QEvent *event)
{
  return this->event_filter_f(obj, event); 
}

And you use this in your code as follows:

MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent)
{ 
   ui = new Ui_MainWindow();
   ui->setupUi(this); // Initialise widgets
   this->wire_up_gui(); // Connect signals and slots

   ui->displayWidget->installEventFilter(new GenericQEventFilter(this, [&] (QObject *obj, QEvent *event) {
     if(event->type() == QEvent::Paint) {
       paint_display_widget(obj, event);
       return true;
     }
     return false;
   }));
}
Zendel
  • 485
  • 3
  • 14
0

"Warning: When the paintdevice is a widget, QPainter can only be used inside a paintEvent() function or in a function called by paintEvent(); that is unless the Qt::WA_PaintOutsidePaintEvent widget attribute is set. On Mac OS X and Windows, you can only paint in a paintEvent() function regardless of this attribute's setting."

From: QT Docu

D-rk
  • 5,513
  • 1
  • 37
  • 55