diff options
| -rw-r--r-- | .gitignore | 3 | ||||
| -rw-r--r-- | Makefile | 26 | ||||
| -rw-r--r-- | README.md | 80 | ||||
| -rw-r--r-- | main.cpp | 11 | ||||
| -rw-r--r-- | mainwindow.cpp | 13 | ||||
| -rw-r--r-- | mainwindow.h | 19 | ||||
| -rw-r--r-- | mainwindow.ui | 21 |
7 files changed, 173 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..872afed --- /dev/null +++ b/.gitignore | |||
| @@ -0,0 +1,3 @@ | |||
| 1 | moc_* | ||
| 2 | ui_* | ||
| 3 | run | ||
diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..4ba3ce9 --- /dev/null +++ b/Makefile | |||
| @@ -0,0 +1,26 @@ | |||
| 1 | QTINCPATH = /usr/include/qt6 | ||
| 2 | QTTOOLS = /usr/lib64/qt6/libexec | ||
| 3 | |||
| 4 | CC = g++ | ||
| 5 | MOC = ${QTTOOLS}/moc | ||
| 6 | UIC = ${QTTOOLS}/uic | ||
| 7 | INCLUDE = -I ${QTINCPATH} \ | ||
| 8 | -I ${QTINCPATH}/QtWidgets | ||
| 9 | QTLIB = -lQt6Widgets \ | ||
| 10 | -lQt6Core \ | ||
| 11 | -lQt6Gui | ||
| 12 | SRC = main.cpp mainwindow.cpp moc_mainwindow.cpp | ||
| 13 | |||
| 14 | all: moc ui | ||
| 15 | ${CC} ${SRC} ${INCLUDE} ${QTLIB} -o run | ||
| 16 | |||
| 17 | moc: | ||
| 18 | ${MOC} mainwindow.h > moc_mainwindow.cpp | ||
| 19 | |||
| 20 | ui: | ||
| 21 | ${UIC} mainwindow.ui > ui_mainwindow.h | ||
| 22 | |||
| 23 | clean: | ||
| 24 | rm moc_* ui_* run | ||
| 25 | |||
| 26 | .PHONY: all moc ui clean | ||
diff --git a/README.md b/README.md new file mode 100644 index 0000000..a56ea9e --- /dev/null +++ b/README.md | |||
| @@ -0,0 +1,80 @@ | |||
| 1 | # A minimal QT application, without the nonsense | ||
| 2 | |||
| 3 | This repository contains a minimal QT application that can be compiled | ||
| 4 | without using CMake or QT Creator. | ||
| 5 | |||
| 6 | ## Requirements | ||
| 7 | |||
| 8 | * A C++ compiler (tested with GCC 14.2.1 and Clang 19.1.7, both on Linux-x86_64) | ||
| 9 | * QT libraries and headers | ||
| 10 | * The QT development tools `moc` and `uic` | ||
| 11 | |||
| 12 | On Fedora Linux they are contained in the `qt6-qtbase-devel`. I have | ||
| 13 | not tested this on other operating systems. | ||
| 14 | |||
| 15 | ## tl;dr | ||
| 16 | |||
| 17 | If you just want to try out this program you can run (if you have `make` installed) | ||
| 18 | |||
| 19 | ``` | ||
| 20 | $ make && ./run | ||
| 21 | ``` | ||
| 22 | |||
| 23 | ## Explanation | ||
| 24 | |||
| 25 | Following the most basic QT Creator template, there are 4 source code files: | ||
| 26 | |||
| 27 | * `main.cpp`: the main source file | ||
| 28 | * `mainwindow.h`: the header file for the main window of the application | ||
| 29 | * `mainwindow.cpp`: the C++ source for the main window | ||
| 30 | * `mainwindow.ui`: the UI file with an XML description of the main window | ||
| 31 | |||
| 32 | The compilation is done in 3 steps: | ||
| 33 | |||
| 34 | 1. Pre-process `mainwindow.h` with `moc` to obtain `moc_mainwindow.cpp` | ||
| 35 | 2. Compile `mainwindow.ui` with `uic` to obtain `ui_mainwindow.h` | ||
| 36 | 3. Compile the C++ files, including `moc_mainwindow.cpp` | ||
| 37 | |||
| 38 | The `Makefile` implements these three steps. | ||
| 39 | |||
| 40 | The first two steps are straightforward: first you need to locate the | ||
| 41 | `moc` and `uic` command - they are usually in the QT installation | ||
| 42 | folder. For example I have them in `/usr/lib64/qt/libexec`. Then run: | ||
| 43 | |||
| 44 | ``` | ||
| 45 | $ /usr/lib64/qt/libexec/moc mainwindow.h > moc_mainwindow.cpp | ||
| 46 | $ /usr/lib64/qt/libexex/uic mainwindow.ui > ui_mainwindow.h | ||
| 47 | ``` | ||
| 48 | |||
| 49 | These steps can be skipped if one prefers to write the `moc_` and `ui_` | ||
| 50 | files directly, removing the dependency on the two tools. | ||
| 51 | |||
| 52 | For the last step, one needs to include the header files and link with | ||
| 53 | the QT libraries. | ||
| 54 | |||
| 55 | On my system the header files are in `/usr/include/qt6`. This means I | ||
| 56 | need to add the option `-I /usr/include/qt6` to my `gcc` command. This | ||
| 57 | simple project also requires headers contained in a subfolder of this, | ||
| 58 | so I will add a second `-I` option (see the full command below). | ||
| 59 | |||
| 60 | As for the system libraries, in my case they are installed in a system | ||
| 61 | folder that is scanned by default by the linker, so I don't have to | ||
| 62 | specify the path. We need the files `libQt6Widgets.so`, `libQt6Core.so` | ||
| 63 | and `libQt6Gui.so`, which we can include with | ||
| 64 | `-lQt6Widgets -lQt6Core -lQt6Gui`. If your linker does not find them, | ||
| 65 | locate them and include their folder with `-L /path/to/the/folder`. | ||
| 66 | |||
| 67 | So the command for step 3 becomes: | ||
| 68 | |||
| 69 | ``` | ||
| 70 | $ g++ main.cpp mainwindow.cpp moc_mainwindow.cpp \ | ||
| 71 | -I /usr/include/qt6 -I /usr/include/qt6/QtWidgets \ | ||
| 72 | -lQt6Widgets -lQt6Core -lQt6Gui | ||
| 73 | -o run | ||
| 74 | ``` | ||
| 75 | |||
| 76 | And finally you can enjoy your new app: | ||
| 77 | |||
| 78 | ``` | ||
| 79 | $ ./run | ||
| 80 | ``` | ||
diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..1cd93da --- /dev/null +++ b/main.cpp | |||
| @@ -0,0 +1,11 @@ | |||
| 1 | #include "mainwindow.h" | ||
| 2 | |||
| 3 | #include <QApplication> | ||
| 4 | |||
| 5 | int main(int argc, char *argv[]) | ||
| 6 | { | ||
| 7 | QApplication a(argc, argv); | ||
| 8 | MainWindow w; | ||
| 9 | w.show(); | ||
| 10 | return a.exec(); | ||
| 11 | } | ||
diff --git a/mainwindow.cpp b/mainwindow.cpp new file mode 100644 index 0000000..ebaa88c --- /dev/null +++ b/mainwindow.cpp | |||
| @@ -0,0 +1,13 @@ | |||
| 1 | #include "mainwindow.h" | ||
| 2 | #include "./ui_mainwindow.h" | ||
| 3 | |||
| 4 | MainWindow::MainWindow(QWidget *parent) | ||
| 5 | : QMainWindow(parent), ui(new Ui::MainWindow) | ||
| 6 | { | ||
| 7 | ui->setupUi(this); | ||
| 8 | } | ||
| 9 | |||
| 10 | MainWindow::~MainWindow() | ||
| 11 | { | ||
| 12 | delete ui; | ||
| 13 | } | ||
diff --git a/mainwindow.h b/mainwindow.h new file mode 100644 index 0000000..ef1225e --- /dev/null +++ b/mainwindow.h | |||
| @@ -0,0 +1,19 @@ | |||
| 1 | #include <QMainWindow> | ||
| 2 | |||
| 3 | QT_BEGIN_NAMESPACE | ||
| 4 | namespace Ui { | ||
| 5 | class MainWindow; | ||
| 6 | } | ||
| 7 | QT_END_NAMESPACE | ||
| 8 | |||
| 9 | class MainWindow : public QMainWindow | ||
| 10 | { | ||
| 11 | Q_OBJECT | ||
| 12 | |||
| 13 | public: | ||
| 14 | MainWindow(QWidget *parent = nullptr); | ||
| 15 | ~MainWindow(); | ||
| 16 | |||
| 17 | private: | ||
| 18 | Ui::MainWindow *ui; | ||
| 19 | }; | ||
diff --git a/mainwindow.ui b/mainwindow.ui new file mode 100644 index 0000000..f9481ec --- /dev/null +++ b/mainwindow.ui | |||
| @@ -0,0 +1,21 @@ | |||
| 1 | <?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | <ui version="4.0"> | ||
| 3 | <class>MainWindow</class> | ||
| 4 | |||
| 5 | <widget class="QMainWindow" name="MainWindow"> | ||
| 6 | <property name="geometry"> | ||
| 7 | <rect> | ||
| 8 | <x>0</x> | ||
| 9 | <y>0</y> | ||
| 10 | <width>800</width> | ||
| 11 | <height>600</height> | ||
| 12 | </rect> | ||
| 13 | </property> | ||
| 14 | <property name="windowTitle"> | ||
| 15 | <string>My first QT app, without the nonsense!</string> | ||
| 16 | </property> | ||
| 17 | </widget> | ||
| 18 | |||
| 19 | <resources/> | ||
| 20 | <connections/> | ||
| 21 | </ui> | ||
