bytedeco/javacpp

Qt virtual QObject

Open

#419 opened on Aug 10, 2020

View on GitHub
 (10 comments) (0 reactions) (0 assignees)Java (620 forks)batch import
bugenhancementhelp wanted

Repository metrics

Stars
 (4,279 stars)
PR merge metrics
 (No merged PRs in 30d)

Description

Hi,

I'm trying to implement a custom event function in a class extending QApplication.

public native @Cast("bool") boolean eventFilter(QObject watched, QEvent event);

When overriding this function in java, the new implementation is not called.

Also, this function is missing on the java side:

@Virtual protected native void customEvent(QEvent event);

To fix this, I added this function to qt/src/main/java/org/bytedeco/qt/presets/Qt5Core.java:

@Override
protected String[] virtual() {
return new String[]{"QObject"};
}

I'm using mvn install -DskipTests=true -Djavacpp.cppbuild.skip to update the generated files. This changes will be created in qt/src/gen/java/org/bytedeco/qt/Qt5Core/QObject.java:

-    public native @Cast("bool") boolean event(QEvent event);
-    public native @Cast("bool") boolean eventFilter(QObject watched, QEvent event);
+    @Virtual public native @Cast("bool") boolean event(QEvent event);
+    @Virtual public native @Cast("bool") boolean eventFilter(QObject watched, QEvent event);

+    @Virtual protected native void timerEvent(QTimerEvent event);
+    @Virtual protected native void childEvent(QChildEvent event);
+    @Virtual protected native void customEvent(QEvent event);

But compiling fails:

/(...)/javacpp-presets/qt/target/native/org/bytedeco/qt/linux-x86_64/jniQt5Core.cpp: In function 'jboolean Java_org_bytedeco_qt_Qt5Core_QCoreApplication_event(JNIEnv*, jobject, jobject)':
/(...)/javacpp-presets/qt/target/native/org/bytedeco/qt/linux-x86_64/jniQt5Core.cpp:9555:152: error: 'virtual bool QCoreApplication::event(QEvent*)' is protected within this context
 9555 |         bool rval = (bool)(dynamic_cast<JavaCPP_QCoreApplication*>(ptr) != NULL ? ((JavaCPP_QCoreApplication*)ptr)->super_event(ptr0) : ptr->event(ptr0));
      |                                                                                                                                                        ^
In file included from /(...)/javacpp-presets/qt/target/native/org/bytedeco/qt/linux-x86_64/jniQt5Core.cpp:103:
/(...)/javacpp-presets/qt/cppbuild/linux-x86_64/include/QtCore/qcoreapplication.h:190:10: note: declared protected here
  190 |     bool event(QEvent *) override;
      |          ^~~~~

qobject.h:

public:
  virtual bool event(QEvent *event);

qcoreapplication.h:

protected:
    bool event(QEvent *) override;

Because it is protected in QCoreApplication, it can not be called here (jniQt5Core.cpp):

JNIEXPORT jboolean JNICALL Java_org_bytedeco_qt_Qt5Core_QCoreApplication_event(JNIEnv* env, jobject obj, jobject arg0) {
    QCoreApplication* ptr = (QCoreApplication*)jlong_to_ptr(env->GetLongField(obj, JavaCPP_addressFID));
    if (ptr == NULL) {
        env->ThrowNew(JavaCPP_getClass(env, 6), "This pointer address is NULL.");
        return 0;
    }
    jlong position = env->GetLongField(obj, JavaCPP_positionFID);
    ptr += position;
    QEvent* ptr0 = arg0 == NULL ? NULL : (QEvent*)jlong_to_ptr(env->GetLongField(arg0, JavaCPP_addressFID));
    jlong position0 = arg0 == NULL ? 0 : env->GetLongField(arg0, JavaCPP_positionFID);
    ptr0 += position0;
    jboolean rarg = 0;
    jthrowable exc = NULL;
    try {
        bool rval = (bool)(dynamic_cast<JavaCPP_QCoreApplication*>(ptr) != NULL ? ((JavaCPP_QCoreApplication*)ptr)->super_event(ptr0) : ptr->event(ptr0));
        rarg = (jboolean)rval;
    } catch (...) {
        exc = JavaCPP_handleException(env, 9);
    }

    if (exc != NULL) {
        env->Throw(exc);
    }
    return rarg;
}

In this line: bool rval = (bool)(dynamic_cast<JavaCPP_QCoreApplication*>(ptr) != NULL ? ((JavaCPP_QCoreApplication*)ptr)->super_event(ptr0) : ptr->event(ptr0));, when ptr is of type QCoreApplication, ptr->event is not valid, because it is protected.

I tried this changes: In file org.bytedeco.qt.presets.Qt5Core, in function public void map(InfoMap infoMap) I added

.put(new Info("QObject::event").javaNames("someExampleName"))

this will rename the function as expected. But changing it to:

.put(new Info("QCoreApplication::event").javaNames("someExampleName"))

nothing will be changed. Also

.put(new Info("QCoreApplication::event").skip())

and adding "QCoreApplication::event" to protected String[] skip() is not possible.

Maybe changing ptr->event(ptr0) to ((QObject*)ptr)->event(ptr0) will work?

Is there a way to fix this?

Contributor guide