Trouble using QPainter within paintEvent in QWidget



  • Hello,

    I have trouble understanding how to paint anything in a QWidget using Qpainter within a paintEvent. So here is my trial viewer:

    myviewer.h :

    class MyViewer : public QMainWindow
    {
    	Q_OBJECT
    
    public:
    
    	MyViewer();
    	void paintEvent(QPaintEvent *);
    
    private:
    	QWidget *mainWidget;
    };
    

    implementation:

    MyViewer.cpp :

    MyViewer::MyViewer() : mainWidget(NULL)
    {
    	QWidget *mainWidget = new QWidget(this);//Used as a QPaintDevice.	
    	setWindowTitle(tr("Image Viewer"));
    	setCentralWidget(mainWidget);
    }
    
    void MyViewer::paintEvent(QPaintEvent *)
    {	
    
    	QPainter painter(mainWidget);
    	painter.drawArc(50, 30, 150, 150, 0, 16 * 360);
    	painter.drawArc(200, 80, 100, 100, 0, 16 * 360);
    	painter.drawArc(300, 130, 50, 50, 0, 16 * 360);
    
    }
    

    I'm only trying to reproduce this example, but in a QWidget and not directly in a QMainWindow.

    Things break at the line:
    QPainter painter(mainWidget);

    with these errors:

    ASSERT: "pd !=0" in file painting\qpainter.cpp, line 1468
    QWidget::repaint: Recursive repaint detected
    ASSERT: "pd !=0" in file painting\qpainter.cpp, line 1468

    Any idea ?

    Thanks


  • Lifetime Qt Champion

    Hi,

    You can't paint like that on another widget. The painEvent is valid for the current widget only



  • Hi again SGaist!
    By "current" do you mean "active"? I see in the documentation that there are "active" windows, but fail to see "current" windows. If yes, does the use of "QWidget::activateWindow" would make my QWidget "current" and suffice for QPainter?

    Thanks


  • Lifetime Qt Champion

    No, I mean current, inactive widgets are also painted (e.g. the grayish color of a selection).

    The proper way to paint a widget is what the example is showing: paint in the subclass



  • Ok, I got it working. So as you suggested I wrote a subclass inheriting QWidget :

    PaintWidget.h

    class PaintWidget : public QWidget // QWidget used as the QPaintDevice.
    {
    public:
    
    	PaintWidget();
    	~PaintWidget();
    	void paintEvent(QPaintEvent *);
    };
    

    where paintEvent is implemented by starting with QPainter painter(this);.

    Then this class is used in myviewer.h instead of the QWidget as a private property.

     class MyViewer : public QMainWindow
    {
        Q_OBJECT
    
    public:
    
        MyViewer();
        void paintEvent(QPaintEvent *);
    
    private:
        PaintWidget *mainWidget;
    }; 
    

    The point of all this is to draw different images by using Qsliders, where a modified image will be drawn at each change of position of the Qsliders.
    Nonetheless, still too inexperienced with all this, I must ask, does the use of a QMainWindow, and QPainter within a QWidget-based subclass, within the QMainWindow, will allow theuse of Qsliders ? Or will I only be able to add QSliders with, say, QMdiArea ?

    Thanks


  • Lifetime Qt Champion

    No, you can use QSlider where you want. However from your questions, you should take the time to go trough Qt's examples and demo, you'll see there what you can accomplish.

    What property should your slider act upon ?



  • Yes i'm still experimenting with the examples and demo out there.

    The QSliders will act on the thresholding parameters (min and max of the input image data that are usually 32 bits per channel), and possibly a gamma scaling factor. These are the image properties that we (in my group) need to manipulate often, for this i'm experimenting with Qt to assess its responsiveness.


  • Lifetime Qt Champion

    Then don't hesitate to play, there are several imaging software that uses Qt for that kind of task, take for example Krita (painting) or digiKam (photo management)



  • @SGaist
    Ok, will do! Thanks for the advice!


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.