Getting font metrics without GUI (console mode)
Asked Answered
B

3

9

Let's say some images have to be generated by a Qt console program and that font metrics are needed by internal algorithms (they use the text width/height as input to compute the position where the drawing should occur). This program has to be runable on a Linux without any GUI (runlevel-3, basically a cluster without any display server).

Problem: QFontMetrics are only available when running a Qt application in GUI mode.
Any workaround to get string metrics without any display server ?

Betts answered 30/7, 2015 at 19:44 Comment(4)
Indeed, when trying to use a QFont without application attached it throws 'ASSERT failure in QGuiApplication::font(): "no QGuiApplication instance"'. I know it's not a desirable solution, but you can create a dummy application and use it as a 'container' for the fonts. Just don't execute the app (app.exec()) but delete it after use.Medarda
you need gui module, but you don't need actual UI. Probably you will also need QApplication object (not a QCoreApplication), but you don't have to create any widget.Bultman
yes, but the QApplication calls exit(1) when there's no display server...Betts
@MarekR that was what I meant, creating the QApplication but simply not executing it. You should be able to access it's members normally.Medarda
B
4

Ok after additional comments I think I understand your problem. Just do it like that:

include <QApplication>

int main(int argv, char **args)
{
    QApplication app(argv, args);
    QApplication::processEvents(); // this should allow `QApplication` to complete its initialization

    // do here whatever you need 

    return 0; // or some other value to report errors
}

You can also try use QGuiApplication this version doesn't require (doesn't use) widgets.

See also example in documentation how to handle none gui cases.


This code works perfectly on my Ubnutu with Qt 5.3
#include <QGuiApplication>
#include <QFontMetrics>
#include <QDebug>

int main(int argc, char *argv[])
{
    QGuiApplication a(argc, argv);

    QFont font("Times", 10, QFont::Bold);
    qDebug() << font;
    QFontMetrics metrics(font);

    qDebug() << metrics.boundingRect("test");

    return 0;
}

It also works with Qt 4.8 when QApplication is used.

Project file was quite simple

QT       += core
TARGET = MetricsNoGui
TEMPLATE = app
SOURCES += main.cpp
Bultman answered 10/8, 2015 at 10:37 Comment(2)
Well I'm afraid I granted you the bounty too quickly! lol. It seemed to work, but in fact if you unset the DISPLAY var env (in the terminal where you call that program), it will still crash: "QXcbConnection: Could not connect to display\n Aborted (core dumped)"Betts
:( Doesn't work for me as well when ran with an invalid DISPLAY var like this: DISPLAY=:99 ./MetricsNoGui with the error Could not load the Qt platform plugin "xcb". It works well just with a valid DISPLAY.Lachesis
T
0

Qt 4.8 has such QApplication constructor, whose 3rd parameter can help to solve the issue. Simple provide false as 3rd argument and enjoy using QFontMetrics in Qt console application. There will be no crashes if one starts app on systems without X server.

Technetium answered 15/2, 2019 at 17:7 Comment(0)
L
0

I didn't find a way to use QFont or QPrinter with QCoreApplication :( However, if you are able to install Xvfb, then your QApplication will be runnable also on a server without any display. I'm using this setup on a headless Raspberry Pi Zero.

Xvfb :1 -screen 0 1024x768x16 &
export DISPLAY=:1.0
./YourQApplication

This isn't the most elegant solution, but after hours of desperate searching, it's the only one I found.

Lachesis answered 9/3, 2021 at 17:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.