Building Qt apps on the command line

By Christian Stigen Larsen
Posted 25 Nov 2012 — updated 06 May 2016

Most Qt tutorials seem to assume you want to use Qt Creator. This shows you how to build Qt apps on the command line, meaning you can experiment much quicker while feeling that you're in control.

Create a directory foo and then put the code below into foo.cpp.

#include <qapplication.h>
#include <qpushbutton.h>

int main(int argc, char** argv)
{
  QApplication app(argc, argv);

  QPushButton hello("Hello world!", 0);
  hello.resize(100, 30);
  hello.show();

  return app.exec();
}

Using qmake, set up a new Qt project and create a GNU makefile.

$ qmake -project -o foo.pro

With newer versions of Qt, you have to edit foo.pro after creating it. Add the line qt += WIDGETS to be able to compile:

TEMPLATE = app
TARGET = foo
INCLUDEPATH += .
QT += widgets # <== Add this

# Input
SOURCES += foo.cpp

Now, generate a makefile:

$ qmake -makefile
$ ls
Makefile foo.cpp foo.pro

If you use other parts of Qt, for example networking, you may have to add additional such lines (QT += networking). In that case, you have to recreate the makefile with the above command.

Now you can simply make the app.

$ make

It depends on the system what the final binary will be called. On Mac OS X, it will be foo.app, and on Windows I guess it will be foo.exe. To open the application bundle on OS X, do

$ open foo.app

The result should look similar to the image below.

A 'Hello, world!' desktop application made with Qt

Using the meta-object compiler

You'll soon want to use the meta-object compiler to be able to play with slots and signals. The makefile already supports this, but you have to explicitly call the target to build the .moc files. Type

$ make mocables

to build them. If you copy the below code, this command will create foo.moc. After that, you need to #include "foo.moc" at the end of foo.cpp to make sure the linker doesn't complain about missing vtables.

Here's a really simple example to get you going:

#include <qapplication.h>
#include <qdialog.h>
#include <qmessagebox.h>
#include <qobject.h>
#include <qpushbutton.h>

class MyApp : public QDialog {
  Q_OBJECT
public:
    MyApp(QObject* /*parent*/ = 0):
      button(this)
    {
      button.setText("Hello world!");
      button.resize(100, 30);

      // When the button is clicked, run button_clicked
      connect(&button, &QPushButton::clicked, this, &MyApp::button_clicked);
    }

public slots:
    void button_clicked() {
      QMessageBox box;
      box.setWindowTitle("Howdy");
      box.setText("You clicked the button");
      box.show();
      box.exec();
    }

protected:
  QPushButton button;
};

int main(int argc, char** argv)
{
  QApplication app(argc, argv);

  MyApp myapp;
  myapp.show();

  return app.exec();
}

#include "foo.moc"

Compile with

$ make mocables all
$ open foo.app

This will give you a window with a single button, which opens a pop-up window when clicked.

You can hack the makefile to automatically build foo.moc, but since it's automatically generated, I suggest you either just build the mocables explicitly, or find out how to add the moc targets to foo.pro.