Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

QPainter(QPaintDevice) not working #23

Closed
wolfseifert opened this issue Dec 20, 2021 · 8 comments
Closed

QPainter(QPaintDevice) not working #23

wolfseifert opened this issue Dec 20, 2021 · 8 comments

Comments

@wolfseifert
Copy link

According to Qt 6 documentation

 void MyWidget::paintEvent(QPaintEvent *)
 {
     QPainter p;
     p.begin(this);
     p.drawLine(drawingCode);        // drawing code
     p.end();
 }

and

 void MyWidget::paintEvent(QPaintEvent *)
 {
     QPainter p(this);
     p.drawLine(drawingCode);        // drawing code
 }

should be the same. Translated to QtJambi this means:

var p = new QPainter();
p.begin(glWidget);
//...
p.end();

and

var p = new QPainter(glWidget);
//...

should be the same. But the second approach with QPainter(QPaintDevice) is not working. Line 3286 in QPainter.java

    @io.qt.QtUninvokable
    private void initialize(QPaintDevice device, boolean inConstructor){
        if(device instanceof io.qt.core.QObject){
            io.qt.core.QObject object = (io.qt.core.QObject)device;
            if(object.isWidgetType() || device instanceof QPaintDeviceWindow) {
                java.util.List<QPainter> painters = __paintedDevices.get(device);
                if(painters==null){
                    if(inConstructor)
3286                    throw new QPaintingOutsidePaintEventException();
                }else if(painters.size()==0){
                    threadCheck((io.qt.core.QObject)device);
                    painters = java.util.Collections.singletonList(this);
                    __paintedDevices.put(device, painters);
                }else{
                    threadCheck((io.qt.core.QObject)device);
                    if(painters.size()==1){
                        painters = new java.util.LinkedList<>(painters);
                        __paintedDevices.put(device, painters);
                    }
                    painters.add(this);
                }
            }else {
                threadCheck((io.qt.core.QObject)device);
            }
        }else if(device==null){
            java.util.Objects.requireNonNull(device, "Argument 'QPaintDevice': null not expected.");
        }
    }

throws an exception. The painters are also null in the first approach, but because I am not in a constructor it works fine.

My workaround for now is to use the first approach.

@omix
Copy link
Contributor

omix commented Dec 20, 2021

Qt does not accept paining on widgets outside of paintEvent(QPaintEvent *). Thus, QtJambi checks if it is within paintEvent method when calling QPainter.begin(device) and new QPainter(device).

I thought there is a unit test checking these cases. And I also thought my own program does these things as well. I'll check it.

@wolfseifert
Copy link
Author

This happens within paintEvent. Substituting approach two with approach one resolves the issue (nothing else changed).

@omix
Copy link
Contributor

omix commented Dec 20, 2021

So, using begin(device) works fine but not using constructor?

@omix
Copy link
Contributor

omix commented Dec 20, 2021

Actually, there is a test scenario in unit tests:
io.qt.autotests.TestPaintOnWidget
and here:

  • testPaintingInsideViaConstructor() and
  • testPaintingInsideViaBegin()
    These tests succeed.

Now as I see the tests, I can tell you QPainter.begin(device) never throws an exception. It simply returns false if painting is not allowed.
Thus, new QPainter(device) will throw exception in all scenarios where QPainter.begin(device) will return false.

@omix
Copy link
Contributor

omix commented Dec 20, 2021

Did you call paintEvent directly? In this case, the exception is thrown because paintEvent needs to be called by event loop only.

@wolfseifert
Copy link
Author

I checked again: approach one (begin) works, approach two (constructor) fails within the same context.The context is overriden paintGL() of QOpenGLWidget and called by the framework.

@omix
Copy link
Contributor

omix commented Dec 20, 2021

Ok, I'll add QOpenGLWidget::paintGL() as scenario to TestPaintOnWidget.

@omix omix closed this as completed Dec 27, 2021
@omix
Copy link
Contributor

omix commented Jan 18, 2022

This issue is solved with QtJambi 6.2.2.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants