Porting to Qt5

Boudewijn Rempt boud at valdyas.org
Mon Apr 8 12:05:59 BST 2013


On Mon, 8 Apr 2013, Sebastian Sauer wrote:

> Q_PRIVATE_SLOTS is indeed a problem. For moc-includes: The fundamental 
> problem here is that qmake uses a different moc filename layout then cmake. 
> It cannot be changed in qmake to match to the cmake ones. Lukely this days we 
> got automoc and that means in 99% of the cases we not need to include moc's 
> any longer.

Yes -- intend to do a little py script to remove all those moc includes 
globally.

> Lesser code, lesser error-prune, more portable, yay :) An 
> exception are classes like
>
> test.h
> class A : publci QObject
> {
> private:
> class Private;
> Private *d;
> Q_PRIVATE_SLOT(d, SLOT(mySlot());
> }
>
> test.cpp
> class A::Private
> {
> public:
>    void mySlot() {}
> };
>
> cause here the moc needs to be included in test.cpp to know about the mySlot 
> impl and be abel to call it.
>
> Taken the very limited number of cases where we do that it may an idea to 
> just not use Q_PRIVATE_SLOT.

Well, I'm fine with having moc_bla.cpp includes where Q_PRIVATE_SLOT is 
used. I don't think there's any real problem there.

> 5.1 is/was scheduled for this month iirc. So, it should hit soon. Its also 
> required for Android since Android-support got only introduced in 5.1.

Yeah, as soon as there's a beta tarball to download, I'll update my 
development vm.

>> * kdelibs: add a shim "kofake" library that has enough of the KDE headers 
>> and implementation to build. This mostly is ready, but there is some stuff 
>> missing and currently libs/flake fails to build because of missing stuff.
>
> Oh, interesting. iirc it worked/works for me fine with all of flake.

These are the linking errors I currently get:

Linking CXX shared library libflake.so
CMakeFiles/flake.dir/KoCanvasControllerWidget.cpp.o: In function 
`qobject_cast<QGLWidget*>':
/usr/include/QtCore/qobject.h:473: undefined reference to 
`QGLWidget::staticMetaObject'
CMakeFiles/flake.dir/KoToolManager_p.cpp.o: In function 
`ToolAction::qt_metacall(QMetaObject::Call, int, void**)':
/home/boud/kde/build/calligra/libs/flake/moc_KoToolManager_p.cpp:334: 
undefined reference to `KAction::qt_metacall(QMetaObject::Call, int, 
void**)'
CMakeFiles/flake.dir/KoToolManager_p.cpp.o: In function `~KAction':
/home/boud/kde/src/calligra/fake/kaction.h:11: undefined reference to 
`vtable for KAction'
/home/boud/kde/src/calligra/fake/kaction.h:11: undefined reference to 
`vtable for KAction'
CMakeFiles/flake.dir/KoToolManager_p.cpp.o: In function `KAction':
/home/boud/kde/src/calligra/fake/kaction.h:16: undefined reference to 
`vtable for KAction'
CMakeFiles/flake.dir/KoToolManager_p.cpp.o: In function 
`ToolAction::qt_metacast(char const*)':
/home/boud/kde/build/calligra/libs/flake/moc_KoToolManager_p.cpp:329: 
undefined reference to `KAction::qt_metacast(char const*)'
CMakeFiles/flake.dir/KoToolManager_p.cpp.o:(.data.rel.ro._ZTI10ToolAction[_ZTI10ToolAction]+0x10): 
undefined reference to `typeinfo for KAction'
CMakeFiles/flake.dir/KoToolManager_p.cpp.o:(.data.rel.ro+0x0): undefined 
reference to `KAction::staticMetaObject'
CMakeFiles/flake.dir/KoToolManager.cpp.o: In function 
`qobject_cast<KAction*>':
/usr/include/QtCore/qobject.h:473: undefined reference to 
`KAction::staticMetaObject'
CMakeFiles/flake.dir/tools/KoPathTool.cpp.o: In function `KAction':
/home/boud/kde/src/calligra/fake/kaction.h:17: undefined reference to 
`vtable for KAction'
/home/boud/kde/src/calligra/fake/kaction.h:17: undefined reference to 
`vtable for KAction'
/home/boud/kde/src/calligra/fake/kaction.h:17: undefined reference to 
`vtable for KAction'
/home/boud/kde/src/calligra/fake/kaction.h:17: undefined reference to 
`vtable for KAction'
/home/boud/kde/src/calligra/fake/kaction.h:17: undefined reference to 
`vtable for KAction'
CMakeFiles/flake.dir/tools/KoPathTool.cpp.o:/home/boud/kde/src/calligra/fake/kaction.h:17: 
more undefined references to `vtable for KAction' follow
CMakeFiles/flake.dir/svg/SvgSavingContext.cpp.o: In function `Job':
/home/boud/kde/src/calligra/fake/kio/job.h:246: undefined reference to 
`vtable for KIO::Job'
CMakeFiles/flake.dir/KoShapeController.cpp.o: In function 
`KDialog::slotButtonClicked(int)':
/home/boud/kde/src/calligra/fake/kdialog.h:149: undefined reference to 
`KDialog::buttonClicked(KDialog::ButtonCode)'
CMakeFiles/flake.dir/KoShapeController.cpp.o: In function `~KDialog':
/home/boud/kde/src/calligra/fake/kdialog.h:11: undefined reference to 
`vtable for KDialog'
/home/boud/kde/src/calligra/fake/kdialog.h:11: undefined reference to 
`vtable for KDialog'
CMakeFiles/flake.dir/KoShapeController.cpp.o:(.data.rel.ro._ZTV11KPageDialog[_ZTV11KPageDialog]+0x10): 
undefined reference to `KDialog::metaObject() const'
CMakeFiles/flake.dir/KoShapeController.cpp.o:(.data.rel.ro._ZTV11KPageDialog[_ZTV11KPageDialog]+0x18): 
undefined reference to `KDialog::qt_metacast(char const*)'
CMakeFiles/flake.dir/KoShapeController.cpp.o:(.data.rel.ro._ZTV11KPageDialog[_ZTV11KPageDialog]+0x20): 
undefined reference to `KDialog::qt_metacall(QMetaObject::Call, int, 
void**)'
CMakeFiles/flake.dir/KoShapeController.cpp.o:(.data.rel.ro._ZTI11KPageDialog[_ZTI11KPageDialog]+0x10): 
undefined reference to `typeinfo for KDialog'
collect2: error: ld returned 1 exit status
make[2]: *** [libs/flake/libflake.so.14.0.0] Error 1
make[1]: *** [libs/flake/CMakeFiles/flake.dir/all] Error 2
make: *** [all] Error 2
makeobj[0]: Leaving directory `/home/boud/kde/build/calligra/libs/flake'
boud at linux-pb1y:~/kde/build/calligra/libs/flake>


>> * Replace KPluginLoader with Qt5 plugin loading
>
> This will give us static plugins for free. That means its super easy to just 
> bundle multiple plugins into one or even compile everything static.
>
> There is a limitation with plugins needing to inherit and declare interfaces. 
> In coffice I worked around this. So, in fact Qt plugins are 100% dynamic and 
> can handle everything you throw at them.

Yes, I don't foresee problems here -- it's mostly just manual/scriptable 
work.

>> * replace kconfig with qsettings
>
> I am not sure if that's a good idea. KConfig has a few advantages in KDE land 
> like configuration-overwrites, kiosk. Maybe we could just stick with KConfig 
> and under the hood map to QSettings if needed? Or maybe use an own KoConfig 
> that maps to either KConfig or QSettings?

The latter would be best, I guess. Though kiosk seems dead anyway.

> The other such candidate is KAction vs QAction. KAction enables system-wide 
> shortcuts. But then do we have use for that? Maybe yes for specific things 
> like a "Create Screenshot" in Krita?

Nope -- nothing like that. For KAction, my biggest beef is that it is too 
smart. For krita at least, I want to handle shortcut management myself, 
because shortcuts are used for more than QAction-based actions

>
>> * replace KSaveFile with QSaveFile
>> * replace KTemporaryFile with QTemporaryFile
>> * replace KTempDir with QTemporaryDir
>> * replace KFileWidget/KFileDialog with QFileDialog (initial patch on 
>> reviewboard)
>
> There is no equivalent for KFileWidget in Qt and probably never will be. 
> Well, QDirModel+QListView but that would miss any proper KDE-integration. But 
> then I doubt there are much users of KFileWidget in Calligra

This is the full set:

kexi/main/startup/KexiStartupDialog.cpp
kexi/main/startup/KexiStartupFileHandler.cpp
kexi/widget/KexiConnectionSelectorWidget.cpp
kexi/widget/KexiFileWidget.cpp
krita/ui/kis_layer_manager.cc
libs/kokross/KoScriptManagerAdd.cpp
libs/main/KoExistingDocumentPane.cpp
libs/main/KoMainWindow.cpp
plugins/pictureshape/PictureShapeConfigWidget.cpp
plugins/vectorshape/VectorShapeConfigWidget.cpp
plugins/videoshape/SelectVideoWidget.cpp

But Yue has already started on it.

>> * port all tests from qtest_kde.h to QtTest or QtTestWidgets
>> * KApplication to QApplication
>
> I am not sure about the KApplication/QApplication case either. KApp still 
> provides some additional functionality iirc. Could need some investigation.

That's what the porting guidelines recommend:

Changes in kdeui

     KApplication/KUniqueApplication: use QApplication instead, but make 
sure to:
         Call QCoreApplication::setApplicationName("...")
         Call QCoreApplication::setOrganizationDomain("kde.org")
         Call QApplication::setApplicationDisplayName(i18n("...")) for GUI 
programs
         Use KDBusService for DBus registration, and optional "unique" 
behavior


Boudewijn



More information about the calligra-devel mailing list