Unable to Get Application Icons to Display with GTK4 under Ubuntu - icons

Recent articles about GTK4 detail the changes required for displaying application icons. This article in particular is very helpful in explaining how to deploy desktop files and icons.
I am seeing an issue where the application icons display correctly with GTK3 apps, but the default widget icon displays for GTK4 apps. One thing to mention up front is that I am running Ubuntu 22.04 LTS with the latest updates inside a VirtualBox VM hosted under Windows 10.
To test this behavior, I have created a file called HelloWorld.c that contains the following code, which is derived from The GTK Project's Getting Started page and compiles successfully under both GTK3 and GTK4:
#include <gtk/gtk.h>
static void
activate (GtkApplication* app,
gpointer user_data)
{
GtkWidget *window;
window = gtk_application_window_new (app);
gtk_window_set_title (GTK_WINDOW (window), "Window");
gtk_window_set_default_size (GTK_WINDOW (window), 200, 200);
gtk_window_present (GTK_WINDOW (window));
}
int
main (int argc,
char **argv)
{
GtkApplication *app;
int status;
app = gtk_application_new ("org.gtk.example", G_APPLICATION_FLAGS_NONE);
g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
status = g_application_run (G_APPLICATION (app), argc, argv);
g_object_unref (app);
return status;
}
The file resides in a folder called "$HOME/Projects/HelloWorld3,4" and is compiled to produce executables named HelloWorld3 and HelloWorld4 as follows:
gcc `pkg-config --cflags gtk+-3.0` HelloWorld.c -o HelloWorld3 `pkg-config --libs gtk+-3.0`
gcc `pkg-config --cflags gtk4` HelloWorld.c -o HelloWorld4 `pkg-config --libs gtk4`
HelloWorld3.desktop is as follows. To simplify matters for this example, I am not installing any custom icons. There is already an icon called "preferences-color.png" under /usr/share/icons/hicolor/(icon size)/apps. Of course, "(my home folder)" is simply a placeholder for this example; the actual file on my system contains the correct full path to the executable.
#!/usr/bin/env xdg-open
[Desktop Entry]
Version=1.0
Encoding=UTF-8
Type=Application
Name=Hello World GTK 3
Exec=/(my home folder)/Projects/HelloWorld3,4/HelloWorld3
Comment=Hello World with Application-Specific Icon
Icon=preferences-color
Terminal=false
Categories=Utility;GTK;
X-Desktop-File-Install-Version=0.26
HelloWorld4.desktop is as follows (again, "(my home folder)" is simply a placeholder for this example):
#!/usr/bin/env xdg-open
[Desktop Entry]
Version=1.0
Encoding=UTF-8
Type=Application
Name=Hello World GTK 4
Exec=/(my home folder)/Projects/HelloWorld3,4/HelloWorld4
Comment=Hello World with Application-Specific Icon
Icon=preferences-color
Terminal=false
Categories=Utility;GTK;
X-Desktop-File-Install-Version=0.26
According to the article I referenced at the top of this post, the desktop files can either be copied to $HOME/.local/share/applications or installed under /usr/share/applications using desktop-file-install. Both methods have been attempted, with the same results. For sake of completeness, the latter method was used as follows:
sudo desktop-file-install --dir=/usr/share/applications ./HelloWorld3.desktop
sudo desktop-file-install --dir=/usr/share/applications ./HelloWorld4.desktop
After all is said and done, launching HelloWorld3 shows the preferences-color icon, but launching HelloWorld4 shows the default widget icon. Rebooting has no effect on the outcome.
Hopefully I have provided enough information, but please let me know if you have any questions. Any suggestions on where the issue may lie would be very helpful.

Related

moc failing with 'Undefined interface' with Qt 5.10 in a Docker container

A very simple Qt project fails to build for me with Qt 5.10 in a Docker container (with an image derived from opensuse:tumbleweed). The project is as follows:
sh-4.4# cat test.pro
TEMPLATE = app
TARGET = test
INCLUDEPATH += .
INCLUDEPATH += sub
HEADERS = obj.h sub/iface.h
SOURCES = obj.cpp main.cpp
sh-4.4# cat sub/iface.h
#pragma once
#include <QtPlugin>
class Interface
{
public:
virtual ~Interface () {}
};
Q_DECLARE_INTERFACE (Interface, "org.meh.interface/1.0")
sh-4.4# cat obj.h
#pragma once
#include <QObject>
#include <sub/iface.h>
class Obj : public QObject
{
Q_OBJECT
Q_INTERFACES (Interface)
};
sh-4.4# cat obj.cpp
#include "obj.h"
sh-4.4# cat main.cpp
int main() {}
In this case moc complains as follows:
obj.h:9: Error: Undefined interface
Everything is fine in another container with Qt 5.9, and everything is also fine with Qt 5.10 when the project is built in openSUSE Build Service (which uses something else instead of Docker). Some quick googling did not reveal any relevant bugreports for recent Qt versions.
What could be wrong?
Running moc under strace shows Operation not permitted on various statx calls, which sheds some light on why exactly it fails (also, related to this question). This pull request is hopefully going to fix this.
Did you try to run the container with the --privileged (see Which capabilities are needed for statx to stop giving EPERM)?

How to include a .dll using Qt Creator

I've followed the steps described in https://wiki.qt.io/How_to_link_to_a_dll
but, somehow I still get undefined reference errors.
This is what I did:
add to my .pro file the library folder path via INCLUDEPATH+=
add to my .pro file the .dll via LIBS+=
include the .dll (in my case "okFrontPanelDLL.h") via #include in my code
I don't know if it matters, but my library is taken from: http://intantech.com/files/RhythmStim_API_Release_170328.zip
and the extracted folder contains a single .dll and multiple source and header files (do i have to add all sources and headers from the library via SOURCES+= and HEADERS+=?).
Currently, I can declare a variable based on a class defined in the library
okCFrontPanel *dev;
but accessing functions defined for the class, e.g. calling the constructor like
dev = new okCFrontPanel;
leads to an undefined reference error.
edit: I tried direcly adding the source and header files form the library into my Sources folder instead of linking the library and the code works fine, so there is (probably) at least nothing wrong with how I am trying to use the functionalities of the library.
edit2: further information:
OS: Win 7 64 bit
Qt version: 5.9.0
compiler: MinGW 32bit
file location: /[PROJECT FOLDER]/mylibrary
#include <QCoreApplication>
#include "myLibrary/okFrontPanelDLL.h"
int main(int argc, char *argv[])
{
// QCoreApplication a(argc, argv);
// return a.exec();
printf("hello world\n");
okCFrontPanel *dev;
dev = new okCFrontPanel;
// dev->BoardModel;
// If only one Opal Kelly board is plugged in to the host computer, we can use this.
dev->OpenBySerial();
// Set XEM6010 PLL to default configuration to produce 100 MHz FPGA clock.
dev->LoadDefaultPLLConfiguration();
// Upload RhythmStim bitfile which is compiled from RhythmStim Verilog code.
dev->ConfigureFPGA("mylibrary/main.bit");
printf("omg dis is working\n");
}

Deploy QT plugin with its own DLL depences

I have a QT application app.exe and a QT plugin plugin.dll. My plugin.dll depends on many other dynamic libraries (e.g. lib1.dll, lib2.dll and so on). To distribute my project I have this folder structure (ignoring QT libraries):
app.exe
plugins\
plugin.dll
lib1.dll
lib2.dll
lib3.dll
The problem is that there are too many dependences on libX.dll and I want to hide them in a plugin folder, e.g.:
app.exe
plugin\
plugin.dll
lib1.dll
lib2.dll
lib3.dll
But this way libraries libX.dll are "unseen" to my plugin, so that it cannot be loaded. Is there any way to solve this problem?
I am using this code to import libX.dll in plugin.dll's pro-file:
LIBS += -Lpath -l lib1 -l lib2 -l lib3
One of the ways of solving this problem is:
Link all libraries dynamically (at runtime)
Add extra location to search for the libraries
These changes should be done in plugin.dll code:
/* Declare a pointer to import function */
typedef void (*FUNCTION)();
FUNCTION f;
/* Make system search the DLLs in my plugin folder */
// Variable "app" contains directory of the application, not the plugin
QDir app = QDir(qApp->applicationDirPath());
// Combine path
QString plugin_path = app.filePath("plugins/");
// Adding full path for DLL search
SetDllDirectory(plugin_path.toStdWString().c_str());
/* Linking the library */
QLibrary mylib("mylib.dll");
f = (FUNCTION ) mylib.resolve("function");
if (f != NULL)
f(); // You got the function from DLL
else
return; // DLL could not be loaded
This solution has disadvanges:
It is not platform independent (I think you can avoid using SetDllDirectory in UNIX-like systems but I am not sure)
If you import a lot of functions you will have a lot of pointers
Does any one know pure Qt solution?

meta-qt- yocto layer- change default qt platform (QT_QPA_PLATFORM)

I'm using Yocto buildsystem to create an image for raspberry pi that contains Qt5, but I'm having problems with configuring qtbase properly.
Due to those problems when I run Qt app I get an error:
This application failed to start because it could not find or load the Qt platform plugin "xcb" in "".
Available platform plugins are: eglfs, minimal, minimalegl, offscreen.
Reinstalling the application may fix this problem.
Aborted (core dumped)
On the other hand if I start my app like so:
myApp -platform eglfs
it works properly. The same if I set environment variable QT_QPA_PLATFORM=eglfs - it works.
How can I set my default platform to eglfs and not to xcb?
I have tried to set it like below (in my distro.conf):
DISTRO_FEATURES_remove = "x11"
DISTRO_FEATURES_append = " gles2"
PACKAGECONFIG_GL_pn-qtbase = "gles2"
PACKAGECONFIG_X11_pn-qtbase = ""
PACKAGECONFIG_pn-qtbase += "gles2"
PACKAGECONFIG_pn-qtbase += "dbus udev evdev widgets tools libs"
Unfortunately it did not help and my application still shows this error if I don't set platform explicitly.
all you have to do is:
in /etc/profile, add
export QT_QPA_PLATFORM=eglfs so that every time you logged in the machine, it will automatically does it for you.
Or if you do not know what your graphic backends is. The following is the corresponding
Backend: FB; XWayland; X11
GRAPHICS: eglfs; wayland-egl; xcb
export QT_QPA_PLATFORM=${GRAPHICS}

QMake's CONFIG+=console in CMake

In QMake:
CONFIG += console
How do I get the same effect in CMake?
(specs: Qt 5.0.2, CMake 2.8.10)
You don't do anything: for CMake, it's the default. If you want a Windows application, you'll need to add the WIN32 options to the call to add_executable:
add_executable(<name> [WIN32] [MACOSX_BUNDLE]
[EXCLUDE_FROM_ALL]
source1 source2 ... sourceN)
This will set the linker to look for WinMain instead of main as you'd expect for a Windows GUI app, by setting the CMake internal WIN32_EXECUTABLE.
To ensure qDebug() works correctly, you can add:
/* In Header */
#include <QLoggingCategory>
/* After creating QApplication instance */
QLoggingCategory::defaultCategory()->setEnabled(QtDebugMsg, true);

Resources