How to use QWS_MOUSE_PROTO inside code in Qt - qt

I am using QT to make an application for Embedded linux device. When I started my application, mouse & keyboard was not working. From searching about this problem, I came to know that we need to run below command before starting the application:
export QWS_MOUSE_PROTO="USB:/dev/input/event-mouse"
export QWS_KEYBOARD="USB:/dev/input/event-keyboard"
After running above commands, I was able to use mouse and keyboard in my application. But this looks a bit odd because whenever I need to run my application, I have to run those commands. Also I will be setting my application to auto run after the boot so in that case I won't be able to run those commands. So I was wondering if I can include these commands somewhere in my code so that they automatically run and then application starts. Can anyone please guide me here. Please help. Thanks.

Instead of running your application, you could run a script:
#! /usr/bin/env bash
export QWS_MOUSE_PROTO="USB:/dev/input/event-mouse"
export QWS_KEYBOARD="USB:/dev/input/event-keyboard"
my_application
You can also set the environment variables inside of your application, before Qt is started. Use setenv:
#include <cstdlib>
int main(int argc, char ** argv) {
// Set default values if none are set.
setenv("QWS_MOUSE_PROTO", "USB:/dev/input/event-mouse", 0);
setenv("QWS_KEYBOARD", "USB:/dev/input/event-keyboard", 0);
QApplication app(argc, argv);
...
return app.exec();
}
External QWS_MOUSE_PROTO and QWS_KEYBOARD will override the internal defaults since the override parameter is set to zero. This is the desired behavior.

Related

Unable to Get Application Icons to Display with GTK4 under Ubuntu

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.

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");
}

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);

Non Qt console app in Qt Creator

I want to create the simple console app below in Qt Creator:
#include <iostream>
int main(int argc, char* argv[])
{
std::cout << "Hello WOrld";
return 0;
}
I've seen some possible duplicates on SO, I have ticked the "Run in Terminal" option in Run Settings. A console window does pop up on CTRL+R, but it does not display "Hello World", simply "Press Enter to exit".
The above is by creating an Empty Project.
I have tried creating a "Qt Console Application" which generates the code below. This does work fine, but I want the simple non Qt version above.
#include <QtCore/QCoreApplication>
#include <iostream>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
std::cout << "Hello World";
return a.exec();
}
Besides ticking "Run in Terminal" you need to add "CONFIG += console" to your .pro file (if you are using qmake).
TEMPLATE = app
CONFIG += console
SOURCES += main.cpp
After trying Qt again after a long time, it now works. The project file has "CONFIG -=qt" by default. I'm not sure if this alone would have solved the problem back then, but it is the only difference I can see.
Full .pro file:
TEMPLATE = app
CONFIG += console
CONFIG -= qt
SOURCES += main.cpp
The only fault I can see with that example is that the stream is not flushed (please change the std::cout line to:
std::cout << "Hello World" << std::endl;
However, that is unlikely to be the issue you have, although the following example that I've found at http://www.richelbilderbeek.nl/CppQtHelloWorldConsole.htm implies that it is indeed a buffer handling issue where QtCreator makes some assumptions regarding buffering. (Note that that url adds a std::cin.get() call, which forces the application to pause, and thus, you should certainly see some output).
If you stumbled over this thread, because your application instantly exits and the console just shows "Press enter to exit":
This is how your application behaves, if you launch it from QtCreator and it can't find dependent DLLs (very unhelpful, by the way). To find out what exactly is missing, you can start your application without QtCreator. Dependent DLLs have to be in one of the locations listed here http://msdn.microsoft.com/de-de/library/7d83bc18.aspx.

Force library linking with Qt and google test

I'm trying to write a test suit for my Qt(c++) application using google test, the main problem is that my application consists of one main program and various shared libs. Everything was working just fine, until I tried to do some code coverage using gcov/lcov (which don't operate on dynamic libs), so I modified all my .pro file to have a static lib compilation using :
CONFIG += staticlib create_prl
QMAKE_LFLAGS += -static
LIBS += ../../Libs/lib*.a
The problem is that google test test application is something like this:
int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
so it detects the linkage at runtime, which means that when I compile the test application here is no warning or whatever that indicate a problem, and when running the test application it execute 0 test because it doesn't found any.
my solution (quit annoying one) is to define in each class which will be used for test a phony public static member and do an operation for the main test application on it:
class SETTINGS_TESTS_SHARED_EXPORT SettingsTests: public testing::Test {
public:
SettingsTests();
virtual ~SettingsTests();
static bool dummy;
protected:
virtual void SetUp();
virtual void TearDown();
private:
Settings* _setting0;
Settings* _setting1;
Settings* _setting2;
};
using namespace MBI::SETTINGS;
using namespace MBI::TESTS;
int main(int argc, char **argv) {
SettingsTests::dummy = true;
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
so I can force the linkage of that lib on my application.
I have also found the option -u to do something like that in gcc but doesn't seem to work. have anyone have a way to force static library linking if no symbol can be detected in compile time ?
I don't completely understand the question, it's not explained what ::testing::InitGoogleTest and RUN_ALL_TESTS actually do, and how they're related to dynamic linking.
But: you can make the GNU linker ignore unresolved symbols at link time by using the option --unresolved-symbols=ignore-all , or if you need to pass the option to gcc, -Wl,--unresolved-symbols=ignore-all.
In the google test doc there is a mention of linkage problem with visual c++ dll:
Important note for Visual C++ users
If you put your tests into a library and your main() function is in a different library or in your .exe file, those tests will not run. The reason is a bug in Visual C++. When you define your tests, Google Test creates certain static objects to register them. These objects are not referenced from elsewhere but their constructors are still supposed to run. When Visual C++ linker sees that nothing in the library is referenced from other places it throws the library out. You have to reference your library with tests from your main program to keep the linker from discarding it. Here is how to do it. Somewhere in your library code declare a function:
__declspec(dllimport) int PullInMyLibrary() { return 0; }
If you put your tests in a static library (not DLL) then __declspec(dllexport) is not required. Now, in your main program, write a code that invokes that function:
int PullInMyLibrary();
static int dummy = PullInMyLibrary();
This will keep your tests referenced and will make them register themselves at startup.
In addition, if you define your tests in a static library, add /OPT:NOREF to your main program linker options. If you use MSVC++ IDE, go to your .exe project properties/Configuration Properties/Linker/Optimization and set References setting to Keep Unreferenced Data (/OPT:NOREF). This will keep Visual C++ linker from discarding individual symbols generated by your tests from the final executable.
There is one more pitfall, though. If you use Google Test as a static library (that's how it is defined in gtest.vcproj) your tests must also reside in a static library. If you have to have them in a DLL, you must change Google Test to build into a DLL as well. Otherwise your tests will not run correctly or will not run at all. The general conclusion here is: make your life easier - do not write your tests in libraries!
And the solution adopted is pretty much what I did with g++. I'm suspecting the fact that qmake produce intermediary file moc_* and that my code in linked against that.

Resources