Native look for Qt applications on Gtk systems
We should try to make Qt applications look native.
https://bugreports.qt.io/browse/QTBUG-53844
https://forum.manjaro.org/t/solved-qt-apps-theming-broken-after-last-nights-update/6471
Need to find out why the Ubuntu global menu works for one of the Qt-based AppImages mentioned there but not for the others: http://forum.freecadweb.org/viewtopic.php?f=10&t=15525&start=30#p152606
Update: Adding the appmenu-qt5 or appmenu-qt (for Qt 4 apps) package to the ingredients should improve it for Ubuntu.
Also see https://github.com/probonopd/AppImageKit/issues/125#issuecomment-286194585 (Qt Platform Theme integration plugins for the KDE Plasma workspaces. Unofficial mini version).
See https://github.com/MartinBriza/adwaita-qt to make it look native on GTK.

On Ubuntu, /usr/lib/x86_64-linux-gnu/qt5/plugins/platformthemes/libqgtk3.so is present from the package qt5-gtk-platformtheme. Perhaps we need to find and bundle this or at least symlink to it?
Just side note. Do we have confirmed if QIcon::fromTheme(...) works in AppImage? It seems that my application - https://github.com/martinrotter/textosaurus/releases/tag/0.9.2 - does not work correctly. You can launch it and change icon theme in tools/settings/gui to some custom icon theme - for example Papirus (or other you have installed).
Then if you restart application, the icons for buttons/menus are not loaded correctly. When I use the app outside of AppImage (e.g. I install it with distro package manager), everything works. Is QIcon::fromTheme(..) somehow "sandboxed" away?
Neither linuxdeployqt nor AppImage are sandboxing anything. It is more likely that the application or some Qt library is trying to load something from a hardcoded location within /usr. Can you verify what is going on using sudo strace -eopen -f Your.AppImage 2>&1 | grep ENOENT?
This worked with LXImage-QT on XFCE Vanilla:
- Included GTK theme support plugins for QT5 no AppImage
And run:
lximageqt.AppImage -style=GTK+
And the GTK theme is used instead of Fusion
Maybe a Script checking for Desktop Environment?
QIcon::fromTheme(..) only worked with QT5ct for me
This worked with LXImage-QT on XFCE Vanilla
With which exact AppImage is this working for you? Please provide a URL so that I can test. This would be a big step forward. Thanks.
@probonopd OK, will do tonight. It is just weird.
Btw, just to mention. Flatpak'ed version of the same application does not suffer from the problem.
From https://community.kde.org/Guidelines_and_HOWTOs/Flatpak#Styles_and_integration_with_other_desktops I deduce that when creating an AppImage, one might consider to bundle
- Adwaita icon theme (can't it be assumed to be "there" on the target systems?)
- Adwaita KStyle https://github.com/MartinBriza/adwaita-qt.git
- QGnomePlatform Qt platform theme (according to this, this Qt 5 platform theme applies the appearance settings of GNOME for Qt applications. It does not provide a Qt style itself, instead it requires a style that support both Qt and GTK+.)
inside the AppImage.
What I am not sure about, though, is why all of this is apparently needed for Qt 5 when in fact in earlier versions of Qt it was "just working", and widgets looked like Gtk+ widgets on Gtk+ systems.
What is also not clear to me is the relationship between this issue and Qt vs. KDE and Gtk+ vs. GNOME. What I am looking for is the best way to make all Qt applications (including, but not limited to, KDE ones) look native on Gtk+ systems (including, but not limited to, GNOME ones).
According to Qt's documentation
Plugins linked with a Qt library that has a higher version number will not be loaded by a library with a lower version number.
Example: Qt 5.0.0 will not load a plugin built with Qt 5.0.1.
Plugins linked with a Qt library that has a lower major version number will not be loaded by a library with a higher major version number.
Example: Qt 5.0.1 will not load a plugin built with Qt 4.8.2. Example: Qt 5.1.1 will load plugins built with Qt 5.1.0 and Qt 5.0.3.
I ended up writing a wrapper script that improve (not resovle, KDE dialogs on some system are not native) native look.
FILE_TO_RUN.wrapper
#!/bin/sh
# clear LD_LIBRARY_PATH (set from AppRun)
# without clear "qtpaths --plugin-dir" returns $HERE/usr/lib
OLD_LD_LIBRARY_PATH="${LD_LIBRARY_PATH}"
export LD_LIBRARY_PATH=
SELF="`readlink -f "${0}"`"
EXEC="${SELF%.wrapper}"
HERE="${SELF%/*}"
QT_PLUGIN_PATH="${HERE}/../plugins"
PLUGINS_KF5="`kf5-config --qt-plugins 2>/dev/null`"
[ ! -z ${PLUGINS_KF5} ] && QT_PLUGIN_PATH="${QT_PLUGIN_PATH}:${PLUGINS_KF5}"
PLUGINS_QT5="`qtpaths --plugin-dir 2>/dev/null`"
[ ! -z ${PLUGINS_QT5} ] && [ "${PLUGINS_QT5}" != "${PLUGINS_KF5}" ] && QT_PLUGIN_PATH="${QT_PLUGIN_PATH}:${PLUGINS_QT5}"
export QT_PLUGIN_PATH
export LD_LIBRARY_PATH="${OLD_LD_LIBRARY_PATH}"
exec "${EXEC}" "${@}"
[Desktop Entry] Exec=MyExecutable.wrapper
Note Your AppImage must be bundled/compiled with Qt >= QT_ON_HOST
Thanks @sandman7920, that is very clever. Maybe this should be added to https://cgit.kde.org/scratch/brauch/appimage-exec-wrapper.git/ (discussed at https://github.com/AppImage/AppImageKit/issues/396)?
So sad that Qt 5.2.1 looked correct on Gtk+ based systems like Xubuntu 18.04 but newer Qt versions don't, anymore.

Qt regression, really?! Can anyone confirm that things actually worsened?
From Qt 5.6+ full version definition is embedded in library. On start if (plugin_version <= this.version) try_load(plugin)
objdump -p libQt5Gui.so.5
Version definitions: 1 0x01 0x04de00d5 libQt5Gui.so.5 2 0x00 0x0dcbd2c9 Qt_5_PRIVATE_API 3 0x00 0x00058a25 Qt_5 4 0x02 0x058a2810 Qt_5.0 Qt_5 5 0x02 0x058a2811 Qt_5.1 Qt_5.0 6 0x02 0x058a2812 Qt_5.2 Qt_5.1 7 0x02 0x058a2813 Qt_5.3 Qt_5.2 8 0x02 0x058a2814 Qt_5.4 Qt_5.3 9 0x02 0x058a2815 Qt_5.5 Qt_5.4 10 0x02 0x058a2816 Qt_5.6 Qt_5.5 11 0x02 0x058a2817 Qt_5.7 Qt_5.6 12 0x02 0x058a2818 Qt_5.8 Qt_5.7 13 0x02 0x058a2819 Qt_5.9 Qt_5.8 14 0x02 0x08a28110 Qt_5.10 Qt_5.9 15 0x00 0x08a28111 Qt_5.11 Qt_5.10
Also FILE_TO_RUN.wrapper causes strange behavior inside AppImage
ENV["APPIMAGE"] return /path/to/Application.AppImage.wrapper
This was bug inside application.AppImage, not runtime
This is a nightmare, on some system "KDEPlasmaPlatformTheme.so" cannot be loaded due QImage ABI change, on some is loaded and finally on Kubuntu 18.04 shipped with Qt 5.9.5 my app is with 5.11.0
Cannot mix incompatible Qt library (version 0x50905) with this library (version 0x50b00) Aborted (core dumped)
Progress. In order plugins to be loaded correctly all Qt5 libraries (preferably from qt.io 5.11.0 GLIBC_2.17 compatible) used by them must be shipped with AppImage.
For gtk "platformthemes/libqgtk3.so" plugin must be bundled (preferred from qt.io)
For KDE "platformthemes/KDEPlasmaPlatformTheme.so" (do not bundle this plugin)
libQt5Concurrent.so.5 libQt5Core.so.5 libQt5DBus.so.5 libQt5Gui.so.5 libQt5Network.so.5 libQt5PrintSupport.so.5 libQt5Qml.so.5 libQt5QuickControls2.so.5 libQt5Quick.so.5 libQt5QuickTemplates2.so.5 libQt5Script.so.5 libQt5Svg.so.5 libQt5TextToSpeech.so.5 libQt5Widgets.so.5 libQt5X11Extras.so.5 libQt5Xml.so.5
must be bundled
I will attach list with all libraries used by KDE plugins (extracted from Arch).
Maybe will be a good idea linuxdeployqt to have something like -bundle-kde-deps
Note: libQt5Script is deprecated (used by kio->kded plugin) and must be installed separated
On clean ubuntu/kubuntu install qtpaths returns could not find a Qt installation of https://github.com/AppImage/AppImages/issues/88#issuecomment-398047936
kde_qt5_theme_list.txt kde_qt5_full_list.txt kde_plugins_so.txt
Screenshots
Ubuntu 14.04
Unity

KDE4

Ubuntu 16.04
Gnome

KDE

Ubuntu 18.04
Gnome

KDE

Hi @sandman7920 that looks awesome. Can you achieve the same result when using Qt from https://launchpad.net/~beineri?
All Qt version should be fine as long they are newer than Qt on client machine.
new wrapper https://github.com/sandman7920/AppImageQt5run/releases
To run usr/bin/MyQt5Executable
cd AppDir
cp /some/path/appimage.qt5run usr/bin/MyQt5Executable.qt5run
ln -s usr/bin/MyQt5Executable.qt5run AppRun
This is c++ wrapper linked with Qt 5.1.1.
Wrapper make call to QCoreApplication::libraryPaths() function and return system path.
Executable must be compiled without RPATH/RUNPATH
main.cpp
#include <QCoreApplication>
#include <QStringList>
#include <iostream>
#include <string>
#include <unistd.h>
int main(int /*argc*/, char *argv[], char **envp) {
char *real_path;
char *appDir = getenv("APPDIR");
if (appDir != nullptr) {
real_path = realpath(std::string(appDir).append("/AppRun").c_str(), nullptr);
} else {
real_path = realpath(argv[0], nullptr);
}
if (real_path == nullptr) return 1;
const std::string self(real_path);
size_t pos = self.find(".qt5run");
if (pos == std::string::npos) return 1;
real_path[pos] = '\0';
argv[0] = real_path;
pos = self.find_last_of('/');
const std::string appPath = (pos != std::string::npos) ? self.substr(0, pos) : "";
std::string qt_plugins = std::string(appPath).append("/../plugins");
for (auto const &qstring: QCoreApplication::libraryPaths()) {
qt_plugins.push_back(':');
qt_plugins.append(qstring.toStdString());
}
setenv("QT_PLUGIN_PATH", qt_plugins.c_str(), 1);
if (getenv("QT5_DEBUG_RUN") != nullptr) {
std::cerr << "QT_PLUGIN_PATH: " << qt_plugins << '\n'
<< "EXECUTABLE: " << argv[0] << std::endl;
}
return execve(argv[0], argv, envp);
}
CMakeLists.txt
cmake_minimum_required(VERSION 2.8)
project(AppImageQt5run)
set(APP_NAME "appimage.qt5run")
set(CMAKE_SKIP_BUILD_RPATH TRUE)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_LIST_DIR}/bin")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11 -fPIC -DQT_CORE_LIB")
if(LINK_RUNTIME)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libgcc -static-libstdc++")
endif()
set(QT_ROOT "${CMAKE_CURRENT_LIST_DIR}/Qt_5.1.1")
include_directories(SYSTEM ${QT_ROOT}/include)
include_directories(SYSTEM ${QT_ROOT}/include/QtCore)
link_directories(${QT_ROOT}/lib)
add_executable(${APP_NAME} "main.cpp")
target_link_libraries(${APP_NAME} -Wl,--rpath-link=${QT_ROOT}/lib -lQt5Core)
Can you make an AppImage of an example Qt application on Travis CI using Qt from https://launchpad.net/~beineri?
Tomorrow :) I need some sleep (it's midnight here)
Last wrapper has fundamental logic error. I am assuming all systems have Qt5 installed
I am assuming all systems have Qt5 installed
That, of course, is not something we can assume. Looking forward to the sample app, but no hurries.
https://github.com/sandman7920/Qt5Demo
This demo is build on Ubuntu 16.04 with libraries from https://launchpad.net/~beineri/+archive/ubuntu/opt-qt-5.10.1-xenial
I have build demos with Qt 5.10.1 on purpose. One can see the difference running demos on Ubuntu and then on Arch, Arch is with latest libraries 5.11.0 and demo apps don't have native look in plasma
Qt libraries from qt.io have less external dependencies
objdump -p qt_io/5.11.0/libQt5Gui.so.5|grep NEEDED
NEEDED libQt5Core.so.5
NEEDED libpthread.so.0
NEEDED libGL.so.1
NEEDED libz.so.1
NEEDED libstdc++.so.6
NEEDED libm.so.6
NEEDED libgcc_s.so.1
NEEDED libc.so.6
objdump -p /usr/lib/libQt5Gui.so.5|grep NEEDED libpng16.so.16
NEEDED libQt5Core.so.5
NEEDED libpthread.so.0
NEEDED libGL.so.1
NEEDED libpng16.so.16
NEEDED libharfbuzz.so.0
NEEDED libz.so.1
NEEDED libstdc++.so.6
NEEDED libm.so.6
NEEDED libgcc_s.so.1
NEEDED libc.so.6
Qt libraries from qt.io have less external dependencies
Interesting find!
Arch is with latest libraries 5.11.0 and demo apps don't have native look in plasma
What happens if you bundle the KDE look&feel plugin but NOT its dependencies?
I have rebuild KDEPlasmaPlatformTheme, kio with qt.5.11 and bundle it, but strange crashes starter to happen.
I have rebuild KDEPlasmaPlatformTheme, kio with qt.5.11 and bundle it, but strange crashes starter to happen.
Can you track them down? What is crashing, and why?