Creating a GUI using Qt - c++

Is it possible to create user interfaces using the Qt framework without utilizing the Qt Creator program? It seems that when using this program half of the work must be done by you anyway, so why not learn how it works more fundamentally (insofar as the Qt API is concerned) and implement the programs yourself?
It seems that Qt implements XML files and does a lot of heavy lifting for you when using the creator program (i.e. automatically including class member functions, etc). I have previously implemented GUIs in Java and did not have to dabble in XML. Does Java handle this behind the scenes, or does Qt approach the problem differently?

Qt has more than way to create a GUI. There is the old QtWidgets module which works with "classical" desktop UI widgets and has a C++ API. The XML file is just a convenient way to describe your interface, qmake will generate C++ headers from the XMLs and generate a lot of the boilerplate for you.
If you prefer, you can do all the work yourself entirely in C++ by instantiating the various QWidget subclasses (QMainWindow, QLabel, etc.) and using their APIs.
(I'm not familiar enough with Java to answer that part of the question.)
However, I suggest you to take a look at Qt Quick which allows for a better and more modern way to deal with GUIs, and gives you a lot more freedom. (It's also a lot easier and faster to work with.)
If you want more details on either of them, just write a comment :)

Yes it is possible. I am not going to make any statement on what is the best way because I do not even know how to use Qt Creator. Personally, I just use a text editor to create the source files. I have done that for ten years. I also agree with you on understanding API and structuring of the code.

Yes, here's the code for how to create a simple window and a button.
#include <QApplication>
#include <QPushButton>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QPushButton *quitButton = new QPushButton("Quit", 0);
connect(quitButton, SIGNAL(clicked()), &app, SLOT(quit()));
return 0;
}
A good Qt tutorial:
http://meetingcpp.com/index.php/br/items/an-introduction-into-qt-part-ii.html

QtCreator, if using g++ compiler:
When there are errors in code, allow right-click on errors list then Show Outputs (O shortcut)… and you can see g++ command with all options:
g++ -c -pipe -g -std=gnu++0x -Wall -W -D_REENTRANT -fPIC -D_GLIBCXX_USE_CXX11_ABI=0 -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -I../my-project -I. -I../../../anaconda3/include/qt -I../../../anaconda3/include/qt/QtWidgets -I../../../anaconda3/include/qt/QtGui -I../../../anaconda3/include/qt/QtCore -I. -I. -I../../../anaconda3/mkspecs/linux-g++ -o mainwindow.o ../my-project/mainwindow.cpp
So it only creates a MakeFile in build-your-project-title-Debug (or Release). If you edit it, you have all informations:
MAKEFILE = Makefile
####### Compiler, tools and options
CC = gcc
CXX = g++
DEFINES = -D_GLIBCXX_USE_CXX11_ABI=0 -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB
CFLAGS = -pipe -g -Wall -W -D_REENTRANT -fPIC $(DEFINES)
CXXFLAGS = -pipe -g -std=gnu++0x -Wall -W -D_REENTRANT -fPIC $(DEFINES)
INCPATH = -I../sans_titre -I. -I../../../anaconda3/include/qt -I../../../anaconda3/include/qt/QtWidgets -I../../../anaconda3/include/qt/QtGui -I../../../anaconda3/include/qt/QtCore -I. -I. -I../../../anaconda3/mkspecs/linux-g++
…
You can reproduce it or just use QtCreator to define this MakeFile first then run under CLI with:
make

Related

GCC can not recognize Qt libraries or/and include files

I am trying to compile my Qt app from console. Here is specs:
MCBC 3.0 (has preinstalled Qt and gcc), Qt 4.6.4, gcc v4.1.2, qmake v2.01a.
My test qt app contains only 2 files: basket.pro and main.cpp.
basket.pro:
TARGET = basket
TEMPLATE = app
SOURCES += main.cpp
HEADERS +=
main.cpp:
#include <QtGui/QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
return a.exec();
}
I need to compile that app from console.
I got 2 virtual machines. VM #1 has installed QtCreator, and QtCreator compile this app without troubles, also app can be compiled from the console by "qmake" and "make". But there is VM#2, which does not have installed QtCreator, and it is where problems come from.
I tried compile app by commands "qmake make", trying to use Makefile, created by QtCreator, trying to use only gcc comands with explicitly defined paths to Qt libs, include-files and linked libs, but always I got the same errors. For example, I use 2 gcc comands, which used by QtCreator for successful compile this app:
g++ -c -pipe -g -Wall -W -D_REENTRANT -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/lib/qt46/mkspecs/linux-g++ -I. -I/usr/lib/qt46/include/QtCore -I/usr/lib/qt46/include/QtGui -I/usr/lib/qt46/include -I. -o main.o main.cpp
g++ -o basket main.o -L/usr/lib/qt46/lib -lQtGui -L/usr/lib/qt46/lib -lQtCore -lpthread
And so after executing second command I got same error as always:
[root#ARM basket]# ./build_g++_step2
main.o: In function `basic_string<char, string_char_traits<char>, __default_alloc_template<true, 0> >::data(void) const':
/usr/lib/gcc-lib/i586-linux/2.95.4/../../../../include/g++-3/std/bastring.h:152: undefined reference to `QApplication::QApplication(int &, char **, int)'
/usr/lib/gcc-lib/i586-linux/2.95.4/../../../../include/g++-3/std/bastring.h:152: undefined reference to `QApplication::exec(void)'
/usr/lib/gcc-lib/i586-linux/2.95.4/../../../../include/g++-3/std/bastring.h:152: undefined reference to `QApplication::~QApplication(void)'
/usr/lib/gcc-lib/i586-linux/2.95.4/../../../../include/g++-3/std/bastring.h:152: undefined reference to `QApplication::~QApplication(void)'
collect2: ld returned 1 exit status
Please tell what I missed.
Your GCC compiler is version 2.95 (a much too old version from the previous century, which is not conforming to C++11 standard, and which was known to be quite buggy), since /usr/lib/gcc-lib/i586-linux/2.95.4/is used. Run simply g++ -v or g++ --version to check the version of your compiler. (You could have some PATH issue, or you could have misinstalled your build tools).
You should upgrade your compiler to some much newer version (at least GCC 6 and preferably GCC 7 in july 2017)
BTW, I recommend upgrading also your Qt library. Current version (in july 2017) is Qt5.9 and you should use some Qt5.
Then you need to regenerate your makefile, adding more in QT, as answered by ilbeldus
Notice that you could use pkg-config to help compiling Qt applications (perhaps in your Makefile). You still need to explicitly use moc. For example you might compile some Qt C++ GUI file foo.cc (after having used moc) with e.g.
g++ -Wall -g -c $(pkg-config --cflags Qt5Gui) foo.c
and you would use $(pkg-config --libs Qt5Gui) for link options.
I don't recommend using your old MCBC thing (even with googling I didn't find what that is), notably if it is so obsolete.
You are missing the setup of the QT variable in your .pro file.
Add QT += core gui to it, re-run qmake and try to recompile
See the docs here: http://doc.qt.io/qt-4.8/qmake-variable-reference.html#qt

qmake doesn't invoke uic

I'm aware that there is a couple of questions asked online on similar issues but unfortunately none of them helped me solving this relatively simple-looking one, as the title suggests.
I set up a minimal Qt project in which the problem occurs:
├── main.cpp
├── mainwindow.ui
└── qt.pro
main.cpp:
#include <QtWidgets/QtWidgets>
#include "ui_mainwindow.h"
int main () {
return 0;
}
qt.pro:
TEMPLATE = app
TARGET = qt-qmake-uic-problem
INCLUDEPATH += .
# Input
FORMS += mainwindow.ui
SOURCES += main.cpp
The file mainwindow.ui is the default MainWindow Form provided by Qt Creator.
Now if I run
qmake qt.pro
then a Makefile is created causing this error when make gets executed:
[developer#kdb qt-qmake-uic-problem]$ make
g++ -c -pipe -O2 -march=i686 -mtune=generic -O2 -pipe -fstack-protector-strong -Wall -W -D_REENTRANT -fPIC -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -I. -I. -isystem /usr/include/qt -isystem /usr/include/qt/QtGui -isystem /usr/include/qt/QtCore -I. -I/usr/lib/qt/mkspecs/linux-g++ -o main.o main.cpp
main.cpp:2:28: fatal error: ui_mainwindow.ui: No such file or directory
#include "ui_mainwindow.h"
^
compilation terminated.
make: *** [Makefile:298: main.o] Error 1
According to my best knowledge ui_mainwindow.h must be generated either by qmake or by the Makefile - not by myself invoking uic manually. I must note that something similar happens with moc as well and doing my research I haven't found an explanation neither in the documentation nor in similar issues, although it would be strange if this installation of qmake were broken - I'm running Arch Linux and got Qt SDK from the default repository.
Thank you very much for your help in advice!
Assuming you are using QT-5:
If you want to use UI elements linke a QMainWindow or other QT widgets, you need to enable widgets generally in your project configuration:
QT += widgets
This then activates the processing of the FORMS content like mainwindow.ui in your example, and causes that your code gets linked with the correct libraries.
See also here: http://doc.qt.io/qt-5/qtwidgets-index.html

Qt: How can I make my exe 'weight' less

I'm making a program (let's call it ProgramWP) made with Qt 4.8.5 on a Fedora and based on a QWizard structure with its QWizardPages. The program has more or less 50 classes, 30 of them are QWizardPages.
The thing is that the program executable 'weights' (dunno the english word/expression) 8Mb ( the release version) and I want to know:
Why does it weight so much? Which is the cause?
How can I reduce it?
I need to reduce it because in the product of the enterprise, there are some applications runing, some of them mine. To sup up the exe's:
ProgramMAIN (1.5MiB): the main program of the enterprise.
ProgramMAIN2(600KiB): another important program of the enterprise.
ProgramWP(8MiB): My main program (made with Qt).
ProgramMINI(2.5Mib): My mini version of my main program (made with Qt).
Program3(1.3MiB): My other program made with Qt
As you can see my main program weights so so so much than the main one while the main one is soooo much bigger (ProgramWP is just a little program to configure some easy things).
I'm linking statically some of our libs in ProgramWP and ProgramMINI but so does programMAIn and ProgramMAIN2 so... knowing that ProgramMain2 is 600Kibs with the linked libraries, my ProgramWP should not weight more than that.
This is how I do the linking in the .pro file:
unix:!macx: LIBS += -L$PWD/../../ConfigLib/Release/ -lLib1
INCLUDEPATH += $PWD/../../Lib1
DEPENDPATH += $PWD/../../Libs/Release
unix:!macx: PRE_TARGETDEPS += $PWD/../../Libs/Release/Lib1.a
I've searched and asked and found that I could add the QMAKE_CXX_FLAGS+= -s line to the .pro file to delete the unnecesary symbolsand after doing it and runing the qmake, it stills weight the same (It's like if it was ignored). I've see if gcc uses the -s param and rebuilding I get:
g++ -c -pipe -std=c++11 -s -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fstack-protector --param=ssp-buffer-size=4 -m32 -march=i686 -mtune=atom -fasynchronous-unwind-tables -O2 -Wall -W -D_REENTRANT -DQT_NO_DEBUG -DQT_SCRIPT_LIB -DQT_XML_LIB -DQT_GUI_LIB -DQT_NETWORK_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/lib/qt4/mkspecs/linux-g++ -I../MyProject-I/usr/include/QtCore -I/usr/include/QtNetwork -I/usr/include/QtGui -I/usr/include/QtXml -I/usr/include/QtScript -I/usr/include -I../../Utils -I../../Lib1-I../../Lib2-I../../Lib3-I../../Lib4-I. -I. -I../MyProject-I. -o wp2.o ../MyProject/wpmine.cpp
so as you can see, seems that gcc uses that param so... Any idea of why is it so heavy and how can I fix it?
Thank you so much.
Note: Their programs are made with eclipse and c++ basically while mine is made with Qt. To run it they have isntalled some Qt libraries in the enterprise's product so another question is... could they run my program without that libraries installed? Just putting there the exe and calling it?
Here are some tips to reduce executable size:
You might want to use strip on your executable (in case something went wrong with compiler's -s flag)
Compiling with -Os flag might reduce executable size slightly
Reducing size of the data segment of the executable. Note that every constant (including string literals, static arrays initializers, etc) is stored inside executable and increases it's size:
const char* str = "A very very long string"; // will bloat your executable
BigDataType myData[] = { ... }; // will bloat your executable
Moving embedded resources into external files (or even to the network). Embedded icons, images, strings, etc.) increase binary size dramatically. See QtResource
Reduce usage of the templated code. Massive use of templates (along with their instantiation) is a well known reason of code bloating. This is a trade-off between code size and code beauty.
You might want to try CopperSpice, a fork of Qt, if it does any better.

Error using Qt 5.1.1 in code::blocks

I am trying to combine Code::Blocks IDE and Qt 5.1.1 on my win7 32bit. In CB I use MinGW's g++ compiler which supports C++0x.
I downloaded "qt-windows-opensource-5.1.1-mingw48_opengl-x86-offline.exe" and installed at "D:\Qt-library\5.1.1\mingw48_32\".
Then in CB I added three tools named "qmake -project" , "qmake" and "make" at Tools->Configure tools->add.
"qmake -project" with Executable "D:\Qt-library\5.1.1\mingw48_32\bin\qmake.exe", Parameters: "-project -platform win32-g++"
"qmake" with Excutable same as "qmake -project", no parameter;
"make" with Excutable "D:\Qt-library\Tools\mingw48_32\bin\mingw32-make.exe", no parameter
Working directory all set to "${PROJECT_DIR}"
And I clicked project->properties, selected "This is a custom Makefile"
Then I clickd the "qmake -project" menu item in Tools menu which I created as above, qmake generated a .pro file.
Because I use
#include <QApplication>
instead of
#include <QtGui/QApplication>
in main.cpp file so I added "QT += widgets" in the .pro file.
Then click "qmake" in Tools menu, makefiles are generated. If I directly make, it won't compile, because it doesn't support some C++11 grammars,
so I edited the Makefile.Debug and makefile.Release, it looks like:
CC = gcc
CXX = g++
DEFINES = -DUNICODE -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_NEEDS_QMAIN
CFLAGS = -pipe -fno-keep-inline-dllexport -O2 -Wall -Wextra $(DEFINES)
CXXFLAGS = -pipe -fno-keep-inline-dllexport -O2 -frtti -Wall -Wextra -fexceptions -mthreads $(DEFINES)
I added -std=c++0x at the line CXXFLAGS, so it become
CXXFLAGS = -pipe -std=c++0x -fno-keep-inline-dllexport -O2 -frtti -Wall -Wextra -fexceptions -mthreads $(DEFINES)
(it won't work for my version of MinGW if I use -std=c++11)
Then click "make" in the Tools menu, I get two errors:
I don't know what the hell was that but some how I modified my main function from
int main(int argc, char** argv)
to int qMain(int argc, char** argv). Then make again, the two qMain error disappeared but I got this:
And now, I didn't do any thing, make again, that error disappeared !!!
But generated .exe file won't do anything, either double click or run in command line, nothing would happen (by the way, although I included , I didn't write any Qt code)
If I remove
#include <QApplication>
and build the project in normal way(cancel "This is a custom Makefile" and build directly), my program goes well.
Another thing very weird, I added CONFIG += debug and CONFIG -= release in the .pro file, qmake will generate both Makefile.Debug and Makefile.Release(whatever CONFIG or debug and release is uper or lower case), but generated .o files and .exe files are all in release directory, no debug file, why was that ?
Anyone has any ideas ? I'll be very thankful for your suggestions.
The problem is solved(although not perfectly).
The fact is that the program did do something, but somehow no console window appear(before I add Qt header, I wrote the program in C++ and use cout to print messages), thus no output can be seen, even if I run the program in console. I found this by writing a simple Qt GUI program to print the results, it works. But I don't know the reason why console wouldn't appear with QApplication included but no Qt code in the program (whatever I set project->properties->build targets->select build target options->type to GUI or console).
On the other hand, I can run the Qt GUI program by double clicking the .exe file in the debug directory, but not in Code::Blocks, it pops up "cannot locate program entry InterlockedCompareExchange#12 on dynamic link library libstdc++-6.dll". Thus I can't debug the program through CB.

Cannot use libclang with Qt

I encountered a strange bug when I tried to use libclang in a Qt application.
test.cpp
#include <QApplication>
#include <QMainWindow>
#include <clang-c/Index.h>
int main (int argc, char *argv[]) {
QApplication a(argc, argv);
QMainWindow w;
w.show();
CXIndex index = clang_createIndex(0, 0);
Q_UNUSED(index)
return a.exec();
}
test.pro
QT += core widgets
TARGET = test
TEMPLATE = app
SOURCES += test.cpp
LIBS += -lclang
Shell commands and output:
$ ls
test.cpp test.pro
$ qmake
$ make
g++ -c -pipe -march=x86-64 -mtune=generic -O2 -pipe -fstack-protector --param=ssp-buffer-size=4 -Wall -W -D_REENTRANT -fPIE -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -I/usr/lib/qt/mkspecs/linux-g++ -I. -I/usr/include/qt -I/usr/include/qt/QtWidgets -I/usr/include/qt/QtGui -I/usr/include/qt/QtCore -I. -o test.o test.cpp
g++ -Wl,-O1,--sort-common,--as-needed,-z,relro -Wl,-O1 -o test test.o -lclang -lQt5Widgets -lQt5Gui -lQt5Core -lGL -lpthread
$ ./test
Two passes with the same argument (-alloca-hoisting) attempted to be registered!
Segmentation fault
If I manually run g++ without using qmake, I get the same error:
$ g++ -fPIE test.cpp -o test -I/usr/include/qt -I/usr/include/qt/QtWidgets -lQt5Widgets -lclang
$ ./test
Two passes with the same argument (-alloca-hoisting) attempted to be registered!
Segmentation fault
If I comment the w.show(); line the program compiles and runs even if it enters the main loop without the window shown.
If I comment the CXIndex index = clang_createIndex(0, 0); and Q_UNUSED(index) lines, the program compiles and runs. It enters the main loop with the window visible.
I also compiled this with clang and I get the same error message.
I searched the web and I found only this result with a similar error message but I don't know if and how it can help me: http://comments.gmane.org/gmane.comp.compilers.llvm.devel/34647 .
I am using Qt 5.1 and ArchLinux, I have the clang package (version 3.3) installed which includes the libclang headers and the files /usr/lib/libclang.so and /usr/lib/libclang.a.
What is the reason why this program does not work and how can I fix it?
Update: I've found this page.
Running LIBGL_ALWAYS_INDIRECT=1 ./test works well, but I want more than this. I shouldn't have to set that environment variable to be able to run my program.
I can answer the part of you question about what's going wrong, I don't know how to fix it.
First, removing the CXIndex index = clang_createIndex(0, 0); wouldn't fix things if you didn't have -Wl,--as-needed removing it only fixes it because the linker noticed you didn't actually call into libclang and so didn't actually link your program to it without the CXIndex index = clang_createIndex(0, 0); line.
The reason things a breaking is because whatever Mesa backend you are using (either ATI or NVIDIA) also links against clang. What seems to be happening is that when your program is first loaded and dynamic links resolved the linker goes and loads libclang and other LLVM stuff libclang links to and runs the constructors for global objects, which is how LLVM registers it's built in passes automatically. So at this point all of the built in LLVM passes are registered, then QT starts up and it creates an OpenGL context so Mesa loads the appropriate DRI backend and as it happens on your system that backend uses clang/LLVM, and for some reason it seems that all those constructors run again and LLVM notices that "two" passes (actually the same pass trying to register itself twice) share the same name and aborts your program.
Like I said I don't really know why the constructors are running twice and I don't know how to make it stop. Try asking on the mesa-users mailing list if you don't get an answer there try mesa-dev
Mesa mailing lists: http://mesa3d.org/lists.html
EDIT: You should make sure that your copy of Mesa is linked against the same version of LLVM that you are trying to use, if it's not fixing the pass registration thing will be the least of your problems.
Try doing ls /usr/lib64/llvm/libLLVM-?.?.so if you get two things back you have two versions of libLLVM which is not a problem on it's own, but if you're linking against one version and Mesa links against a different version that might explain things.