Using QPainter with QCoreApplication - c++

We have an application (QCoreApplication) that takes some images as input, does something to them, and exports them again. We now need to add some text to the images, and tried to do this with the QPainter class. It all worked well when using it in one of our other apps (using QApplication), but not in our main QCoreApplication app.
Here is the code:
void drawTextOnImage(QImage* image, const QString& text, const QFont& font)
{
QPainter p;
if (!p.begin(image)) return;
p.setFont(font);
p.drawText(image->rect(), Qt::AlignLeft | Qt::AlignTop | Qt::TextWordWrap, text);
p.end();
}
The application crashes on the drawText line.
Any ideas?
It is a very simple text, so suggestions without using Qt will also be appreaciated.

When using classes from "Qt Gui" like QPainter, you are supposed to use a QGuiApplication, not a QCoreApplication.
You might get lucky and be able to make some GUI stuff works while using only a QCoreApplication. But as you have discovered, it makes your application very brittle. Some classes like QPixmap will print an error message, but others will just crash.
The same is applicable with "Qt Widget": if you use a widget related class, you must use a QApplication.
Note that since QApplication inherits QGuiApplication, if you have a QApplication you can use "Qt Gui".

In case you need to run a non-GUI application on something without a windowing system, you need, aside from creating an instance of QGuiApplication, to also choose an appropriate Qt platform.
For me, offscreen platform worked fine. I was generating images with textual elements and saving them to files on a headless Raspberry Pi. My code then was like the example below. Note that setenv is a POSIX function and may need a replacement on Windows, though I'm not sure whether windowless Windows is a thing at all.
#include <stdlib.h>
#include <QImage>
#include <QPainter>
#include <QGuiApplication>
int main(int argc, char** argv)
{
setenv("QT_QPA_PLATFORM","offscreen",1);
QGuiApplication app(argc,argv);
QImage img(128,128, QImage::Format_RGB888);
img.fill(Qt::white);
QPainter p(&img);
p.drawText(QPoint(0,64), "Works!");
img.save("/tmp/test.png");
}

Related

Is it possible to add background image on QWidget without using QtCreator?

Having trouble adding background image on the widget, even though I referenced the recent codes online.
This is my current code for main.cpp:
#include <QApplication>
#include <QWidget>
int main (int argc, char **argv){
QApplication app (argc,argv);
QWidget *w=new QWidget();
w->setStyleSheet("background-image: url(:/cover.jpg);");
w->setWindowTitle("Test");
w->show();
return app.exec();
}
After executing the code, how come the widget remains blank? Thanks in advance!
QtCreator is an IDE designed by Qt. It's just an interface.
I checked your implementation and I don't see anything wrong. It also work well on my pc. Can you check your image url or try with another image ?
Btw, if you're on linux, try removing : character after url ;
w->setStyleSheet("background-image: url(/cover.jpg);");
EDİT:
If jpg is in the same directory with your application, it should be ;
w->setStyleSheet("background-image: url(./cover.jpg);");
You can give a full path to avoid this kind of errors.
"Is it possible to add background image on QWidget without using QtCreator?"
Yes, of course it is.
QtCreator is just an IDE. You don't need to use it at all to write code using the Qt library.
Just as you can use it to write code that does not use Qt at all.

How to print version of a Qt GUI application to console

I have a GUI application written using Qt Widgets. I've added versioning and I'm planning to write an update manager too. In order this to work the update manager must be able to determine the version of my app. I thought of implementing this by running my app with a version switch then parsing it's output. I did a research and I found out that Qt has some kind of built in solution for this.
Here is an example:
#include "mainwindow.h"
#include <QApplication>
#include <QCommandLineParser>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QApplication::setApplicationVersion("1.0.0");
QCommandLineParser parser;
auto versionOption = parser.addVersionOption();
parser.process(app);
if (parser.isSet(versionOption))
{
MainWindow w;
w.show();
return app.exec();
}
return 0;
}
If I launch this app with a -v or --version command line switch, I get a message box containing the version information.
I need to achieve the same, only the information should be printed to standard output. If the app is launched with the version switch it should only display the version in the console then close.
How could I print the version information to the standard console output with a GUI app?
As we cleared some points in comments let's move on. ;)
Take a look at the documentation (http://doc.qt.io/qt-5/qapplication.html#details). In the detail section you see a sane way how to properly parse and handle command line options.
And here (https://stackoverflow.com/a/3886128/6385043) you can see a possibility for writing to standard output. Notice the QDebug caveat.
In my opinion, stick to the text file. You may generate it during build with qmake using the variable VERSION, which you can also use with QApplication::setApplicationVersion(QString).

Restoring or bringing to front Qt desktop application

I have made my app into a single instance app using the RunGuard code found on this SO question:
Qt: Best practice for a single instance app protection
What I'd like to do is when the user tries to start the application while there is one running is to bring the existing running application to the front, and if minimised, restore it.
In my Delphi Windows programming days I used to broadcast a Windows message from the new application before closing it. The existing app would receive this and restore itself and come to the front.
Is something like this possible with Qt on Windows and Linux platforms?
Did you have any specific trouble with QtSingleApplication? It should be sufficient for what you want and will enable you to send a message to the running application. You just need a slot to get that message and if it matches what you expect then you restore it.
http://doc.qt.digia.com/solutions/4/qtsingleapplication/qtsingleapplication-example-trivial.html
The logview object is also set as the application's activation window. Every time a message is received, the window will be raised and activated automatically.
For some reason setActivationWindow() and activateWindow() don't work for me. This is my workaround:
#include <QWidget>
#include <qtsingleapplication.h>
class Window : public QWidget
{
Q_OBJECT
public:
Window(QWidget *parent = 0) : QWidget(parent) {}
public slots:
void readMessage(const QString &str) { showNormal(); }
};
int main(int argc, char *argv[])
{
QtSingleApplication instance(argc, argv);
Window *window = new Window;
window->show();
QObject::connect(&instance, SIGNAL(messageReceived(const QString &)), window, SLOT(readMessage(const QString &)));
if (instance.sendMessage(""))
return 0;
return instance.exec();
}
#include "main.moc"
In common, it is not possible without IPC. QtSingleApplication provide such IPC, but you will get extra dependency from QtNetwork module. (As #svlasov answered)
First problem that you will have: you can't raise any window of application if this application is not foreground. There are solutions for Windows and OS X, how to force raising of windows.

Qt linguist doesn't translate the strings in ubuntu14.04

There is a simple code for translating. It runs in Ubuntu 14.04.
#include <QtGui>
#include <QApplication>
#include <QLabel>
#include <QTextCodec>
int main (int argc,char *argv[])
{
QApplication app(argc,argv);
QTranslator qtr;
qtr.load("hello.qm");
app.installTranslator(&qtr);
//QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8"));
QLabel *label=new QLabel(QObject::tr("hello"));
label->show();
retrun app.exec();
}
I had followed the below steps to translate hello to the chinese 你好 by Qt linguist:
add TRANSLATIONS +=hell0.ts to hello.pro and lupdate.
open the Qt linguist and find that the interface is
It is not like the normal Qt linguist interface. This is my first problem. How can i fix it?
Then i print 你好 to translate 'hello', but nothing is displayed in the blank.
I still push the 'done' button.
I use gedit to open the hello.ts and see that it has been tranlated to 你好.
The picture is
(3) I use 'lrelease' command and get the hello.qm
Last, i run the code as aboved. But the result is just to print 'hello' out.
It doesn't translate 'hello' to 你好. This is my second problem.
I also had used other methods like QtTextCodec::setCodecForTr instead of Qt linguist,but it still doesn't work.
Try to call retranslateUI(this) so the Translation will be updated

First time using Qt: How to display an image?

Noob: How to display an image
I am very new to this, just starting actually. I need to figure out how to display an image on screen.
First I tried:
Source code:
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QGraphicsScene scene;
QGraphicsView view(&scene);
QPixmap qp = QPixmap("../images/tank2.bmp");
if(qp.isNull())
{
printf("Yes its null\n");
}
else
{
QGraphicsPixmapItem item(QPixmap("../images/tank2.bmp"));
scene.addItem(&item);
}
view.show();
return a.exec();
}
from:
Qt jpg image display
it compiles and runs but doesn't show an image. returns 0, etc.
Then I just sorta messed around from there. I'm also curious about something: In Qt editor they show a file structure that doesn't exist on the disk. They have files "Headers", "Sources", and Resources whereas on the systems its just a folder "projectname" with all the files in one folder. Is this just for visual clarity?
The version of QtCreator I'm using is 2.4.1 running Qt 4.7.4 64 bit.
My eventual goal is to make a widget where a picture is a clickable icon where you select that pic and can place it on a larger screen like a tile.
Another Question: Why does Qt have things like "QString" and "QChar"? Is there something wrong with the normal c++ libraries?
If you just want to display a simple image then make a Qlabel the central widget and call setPixmap() passing it your image path
"Another Question: Why does Qt have things like "QString" and "QChar"?
Is there something wrong with the normal c++ libraries?"
Yes there is lots wrong with the normal libraries - at least for std::string.
When Qt was started there wasn't very good cross platform STL support and the standard libraries were very bad at Unicode and support for translations. QString doesthis very well - although I think a combination of modern STL and boost can probably do everything QString can do.
Almost all of the Qt types are automatically reference counted so you can pretty much ignore memory management for them AND pass them around freely. There are also some tricks Qt can do because the extra MOC compile pass means it has Java-like introspection that standard C++ doesn't.
But in general you are free to use standard C++ types (Qt: Qt classes vs. standard C++)
Tested like this, it works. Don't forget to create qrc file.
#include <QtGui/QApplication>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QGraphicsPixmapItem>
#include "mainwindow.h"
#include <stdio.h>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QGraphicsScene scene;
QGraphicsView view(&scene);
QPixmap qp = QPixmap(":/images/123.bmp");
if(qp.isNull())
{
printf("Yes its null\n");
}
else
{
printf("HAHA");
QGraphicsPixmapItem *item = new QGraphicsPixmapItem(QPixmap(":/images/123.bmp"));
scene.addItem(item);
}
view.show();
return a.exec();
}
Here are qrc file:
<RCC>
<qresource prefix="/">
<file>images/123.bmp</file>
</qresource>
</RCC>
And .pro file
QT += core gui
TARGET = testimage
TEMPLATE = app
SOURCES += main.cpp
RESOURCES += 123.qrc
I think your problem is here:
{
QGraphicsPixmapItem item(QPixmap("../images/tank2.bmp"));
scene.addItem(&item);
}
item goes out of scope before you'll actually use it.
I'm also pretty sure you meant that to use the QPixmap that you loaded earlier at the top-level scope.
Generally speaking, you want to limit your questions on SO to a single question... but to address your last question: QChar and QString allow the Qt libs to make several assumptions about strings. The most obvious of which is that QStrings have a standardized encoding.