How do I create a simple Qt console application in C++? - c++

I was trying to create a simple console application to try out Qt's XML parser. I started a project in VS2008 and got this template:
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
return a.exec();
}
Since I don't need event processing, I was wondering whether I may get into trouble if I neglect to create a QCoreApplication and running the event loop. The docs state that it's recommended in most cases.
For the sake of curiosity however, I am wondering how could I make some generic task execute on the event loop and then terminate the application. I was unable to google a relevant example.

Here is one simple way you could structure an application if you want an event loop running.
// main.cpp
#include <QtCore>
class Task : public QObject
{
Q_OBJECT
public:
Task(QObject *parent = 0) : QObject(parent) {}
public slots:
void run()
{
// Do processing here
emit finished();
}
signals:
void finished();
};
#include "main.moc"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
// Task parented to the application so that it
// will be deleted by the application.
Task *task = new Task(&a);
// This will cause the application to exit when
// the task signals finished.
QObject::connect(task, SIGNAL(finished()), &a, SLOT(quit()));
// This will run the task from the application event loop.
QTimer::singleShot(0, task, SLOT(run()));
return a.exec();
}

Don't forget to add the
CONFIG += console
flag in the qmake .pro file.
For the rest is just using some of Qt classes.
One way I use it is to spawn processes cross-platform.

You don't need the QCoreApplication at all, just include your Qt objects as you would other objects, for example:
#include <QtCore>
int main()
{
QVector<int> a; // Qt object
for (int i=0; i<10; i++)
{
a.append(i);
}
/* manipulate a here */
return 0;
}

I managed to create a simple console "hello world" with QT Creator
used creator 2.4.1 and QT 4.8.0 on windows 7
two ways to do this
Plain C++
do the following
File- new file project
under projects select : other Project
select "Plain C++ Project"
enter project name
5.Targets select Desktop 'tick it'
project managment just click next
you can use c++ commands as normal c++
or
QT Console
File- new file project
under projects select : other Project
select QT Console Application
Targets select Desktop 'tick it'
project managment just click next
add the following lines (all the C++ includes you need)
add "#include 'iostream' "
add "using namespace std; "
after QCoreApplication a(int argc, cghar *argv[])
10 add variables, and your program code..
example: for QT console "hello world"
file - new file project 'project name '
other projects - QT Console Application
Targets select 'Desktop'
project management - next
code:
#include <QtCore/QCoreApplication>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
cout<<" hello world";
return a.exec();
}
ctrl -R to run
compilers used for above MSVC 2010 (QT SDK) , and minGW(QT SDK)
hope this helps someone
As I have just started to use QT recently and also searched the Www for info and examples to get started with simple examples still searching...

You could fire an event into the quit() slot of your application even without connect().
This way, the event-loop does at least one turn and should process the events within your main()-logic:
#include <QCoreApplication>
#include <QTimer>
int main(int argc, char *argv[])
{
QCoreApplication app( argc, argv );
// do your thing, once
QTimer::singleShot( 0, &app, &QCoreApplication::quit );
return app.exec();
}
Don't forget to place CONFIG += console in your .pro-file, or set consoleApplication: true in your .qbs Project.CppApplication.

You can call QCoreApplication::exit(0) to exit with code 0

Had the same problem. found some videos on Youtube.
So here is an even simpler suggestion. This is all the code you need:
#include <QDebug>
int main(int argc, char *argv[])
{
qDebug() <<"Hello World"<< endl;
return 0;
}
The above code comes from
Qt5 Tutorial: Building a simple Console application by
Dominique Thiebaut
http://www.youtube.com/watch?v=1_aF6o6t-J4

Related

Getting error : Must construct a QGUIApplication first

I am developing a GUI application, but whenever I am trying to close the application, it throws an error that "Must construct QGuiapplication first". My main is not returning exit code 0, so it's not exiting normally. I think some destructor is getting called twice but need some help here. I am attaching main.cpp code here for reference.
#include <QGuiApplication>
#include <QFontDatabase>
#include <QtWebEngine>
#include "ApplicationManager.h"
#include "AppLogger.h"
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QCoreApplication::setAttribute(Qt::AA_UseOpenGLES);
QGuiApplication app(argc, argv);
QtWebEngine::initialize();
app.setApplicationName("MCS3.0");
QFontDatabase::addApplicationFont(":/Fonts/Roboto.ttf");
#ifdef VERSION
app.setApplicationVersion(QString("%1").arg(VERSION));
logInfoMessage(app.applicationName()+app.applicationVersion()+" Started");
#endif
ApplicationManager::instance().run();
return app.exec();
}
The relevant part of the problem is inside ApplicationManager.h which was not exposed by OP.
I bet that it makes another instance of QApplication (or QGUIApplication or QCoreApplication).
How can I know this? It's partly a guess (as the name looks like) and partly result of the following test:
testQApp.cc:
#include <QtWidgets>
int main(int argc, char **argv)
{
QApplication app(argc, argv);
{ QApplication app(argc, argv);
QLabel qLbl("The app in app");
qLbl.show();
app.exec();
}
return app.exec();
}
testQApp.pro:
SOURCES = testQApp.cc
QT = widgets
Compiled and tested in cygwin64 on Windows 10:
$ qmake-qt5 testQApp.pro
$ make
$ ./testQApp
When I quit the application, the issue occurs:
QApplication::exec: Please instantiate the QApplication object first
Segmentation fault (core dumped)
$
To make this complete, the relevant paragraph of doc. about QApplication:
For any GUI application using Qt, there is precisely one QApplication object, no matter whether the application has 0, 1, 2 or more windows at any given time. For non-QWidget based Qt applications, use QGuiApplication instead, as it does not depend on the QtWidgets library.
Please, note that the emphasize is not done by me.

Specific shortcuts not working on QT

I have some problems with Qt Shortcuts. I extracted my problem into a simple piece of code I am reporting here.
In my code, I want my EmptyMainWindow::onShortcutActivated() to be executed when I press the CTRL + SHIFT + A combination on the keyboard.
Here is my main.cpp
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
EmptyMainWindow w;
w.show();
return a.exec();
}
Here is my EmptyMainWindow Class
#include "emptymainwindow.h"
#include "ui_emptymainwindow.h"
#include <QShortcut>
#include <QDebug>
EmptyMainWindow::EmptyMainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::EmptyMainWindow)
{
ui->setupUi(this);
QShortcut *shortcut = new QShortcut (QKeySequence
(Qt::CTRL + Qt::SHIFT + Qt::Key_A ), this);
connect (shortcut, SIGNAL(activated()), this, SLOT(onShortcutActivated()));
}
void EmptyMainWindow::onShortcutActivated()
{
qDebug() << "EmptyMainWindow::onShortcutActivated()";
}
Now, my problem is that this code does not work in this way but works properly if the shortcut is CTRL+SHIFT+B or CTRL+SHIFT+C, etc.
Do you have any idea on why this is happening?
PS: I am working on Windows 7 with the visual studio compiler
Thank you
I have found the reason. Thanks to a software called Windows Hotkey Explorer, that gives all the shortcuts that have been registered to the operating system, I have discovered that another program was kind of reserving this shortcut and, thus, it wasn't passed to my application. Do you have any idea on how is it possible to do that on Windows?
Maybe this is an issue with QWERTY and AZERTY keyboard. Because on the both C and B have the same position but not A. Have you try to trigger your shortcut with CTRL+SHIFT+Q ?

Qt5, symbolic link to a folder

A dupe-ish question of this question, which (possibly) has got an outdated answer, as I can't get it to work in Qt5.
I wish to create a symbolic link to a folder for a result similar to QFile::link(). Given that QDir doesn't have an equivalent function, QProcess (or an external library) seems like the way out if I'm up to snuff. How would this be managed in Qt5?
Big thanks in advance.
There are shortcuts and hardlinks on Windows. I think mklink refers to hardlinks.
It works for shortcuts:
#include <QCoreApplication>
#include <QFile>
#include <QDebug>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QFile dir("D:\\source-dir");
bool ok = dir.link("D:\\target-dir.lnk");
if (ok)
{
qDebug() << "yeah!";
return 0;
}
else {
qDebug() << "Did not work :(";
return 1;
}
}
In this case you will find a shortcut in the Explorer but you cannot access the file D:\source-dir\Bitmap.bmp by typing D:\target-dir\Bitmap.bmp
I found out that it cannot be done in Qt, so I ended up using the Win32 API instead. Specifically the CreateSymbolicLink() function.

mcvs qwt - must construct a QApplication before a QPaintDevice

I would like to ask if you could help me with my app.
I have an application in C++ using Qt (and Qwt) in MCVS 2010. I want to open QDialog window with QwtPlot on button click from Main Window (QMainWindow). Here is some code:
MainWindow.cpp
void MainWindow::on_pushButton_1_clicked ()
{
Dialog_plot dp;
dp.setModal(true);
dp.exec();
}
Dialog_plot.cpp:
#include <qwt_plot.h>
#include <qwt_plot_canvas.h>
#include <qwt_plot_curve.h>
#include "Dialog_plot.h"
Dialog_plot::Dialog_plot(QWidget *parent)
{
plot = new QwtPlot();
//more code...
main.cpp:
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
This code is compiling, but when I click on that pushbutton_1 in my application I'm getting error:
Must construct a QApplication before a QPaintDevice
I know that such error was discussed many times and I was reading a lot about it but I can't see solution for my problem.
One more thing I would like to mention - I have similar application with Qwt plot written by somebody else and his application compiles and works without any problems in my MCVS. I was trying to compare Linker/libraries included but it seems to be the same. So I guess there is a problem with my application, I just can't solve it. I really need some help!

Qt console application "WARNING: QApplication was not created in the main() thread"

I'm creating a very simple C++ QT console application from an example given here on stack overflow.
How to use QFileSystemWatcher to monitor a folder for change
The code is exactly as the code in that application and I'm developing with Qt's UI, Qt Creator with MinGW 32bit. I selected the console application from the projects I could choose as I have no need for a graphical user interface. Once the application has finished loading, the application shows the error message "WARNING: QApplication was not created in the main() thread" then does nothing.
I have tried debugging the application but get no breakpoints hit, I don't think debugging is working in the editor.
I had a quick go and changed the QApplication to a QCoreApplication seen as I am developing a console application but get the exact same error message.
filesystemreceiver.h
#ifndef FILESYSTEMRECEIVER_H
#define FILESYSTEMRECEIVER_H
#include <iostream>
using namespace std;
#include <QtCore/QApplication>
#include <QtCore/QFileSystemWatcher>
#include <QtCore/QDebug>
#include <QtWidgets/QWidget>
#include <QtWidgets/QMessageBox>
class MyClass : public QWidget
{
Q_OBJECT
public:
MyClass(QWidget* parent=0)
:QWidget(parent){}
~MyClass() {}
public slots:
void showModified(const QString& str)
{
Q_UNUSED(str)
cout << "A message has been received!" << endl;
//QMessageBox::information(this,"Directory Modified", "Your Directory is modified");
}
};
#endif // FILESYSTEMRECEIVER_H
main.cpp
#include <iostream>
using namespace std;
#include <QtCore/QApplication>
#include <QtCore/QFileSystemWatcher>
#include <QtCore/QDebug>
#include <QtWidgets/QWidget>
#include <QtWidgets/QMessageBox>
#include "fileSystemReceiver.h"
int main(int argc, char* argv[])
{
QApplication app(argc, argv);
QFileSystemWatcher watcher;
watcher.addPath("C:/QtTest");
QStringList directoryList = watcher.directories();
Q_FOREACH(QString directory, directoryList)
qDebug() << "Directory name" << directory <<"\n";
MyClass* mc = new MyClass;
QObject::connect(&watcher, SIGNAL(directoryChanged(QString)), mc, SLOT(showModified(QString)));
return app.exec();
}
My pro file looks like this:
QT += core
QT += widgets
QT -= gui
TARGET = fsw
CONFIG += console
CONFIG -= app_bundle
TEMPLATE = app
HEADERS += fileSystemReceiver.h
SOURCES += \
main.cpp
You have had several issues ongoing in your project:
QCoreApplication in a program that is supposed to show a QWidget
Calling the main.cpp source file main.moc. That indicates that you do not quite understand how moc works and what it is about.
cout in a Qt program as opposed to QTextStream or qDebug().
Q_FOREACH in a source code not reused by other application, and hence no collision could normally occur. You should use "foreach" simply.
You are not using const reference for the string while iterating with the foreach even though you seem to be only reading it, not modifying.
You have hard coded path here instead of a const string in a well separated place: watcher.addPath("C:/QtTest");
You are adding widgets to the CONFIG variable, but you remove gui.
You are adding `core to the CONFIG variable when that is in there by default.
You include #include <QtWidgets/QFoo> instead of #include <QFoo> to keep the option of building with Qt 4, and in general with clearly buildsystem include paths.
You are adding CONFIG += console for a non-console based application.
You are adding CONFIG -= app_bundle for a non-console based application.
You are using back-slash for the SOURCES variable, but not for the HEADERS. This is inconsitent.
You create a MyClass instance on the heap as opposed to the stack to make it simpler for you as it is already properly guarded by the event loop to remain valid for the intended scope.
On top of all that, your issue seems to be with qDebug() based on the comment discussion. You should follow the document below how to set up QtCreator for debugging properly.
Setting Up Debugger