How can I from within my code determine if my application is started from Qt Creator (either by "F5" or "Ctrl + R")?
The reason why I want to know this is because I want to create my own debug message handler ( using qInstallMessageHandler()) only when the application is launched from the executable directly. Since Qt allows only one message handler, I don't want to create my own when launching from Qt Creator, or else I can't see the debug messages in Qt Creators own debug console.
I don't think there is an easy way to detect that.
You could add a command line argument to the run settings in QtCreator though, and check for that at runtime.
I have two possible solutions:
check the names of parent process (or parent of parent)
there are multiple ways to do this: under Posix (mingw, linux etc..) you have getppid(). Under Windows you can check the namehave the Psapi or other process handling functions. I have done this for other purposes in the past and it works reliably as long as the process names do not change. Alternatively you could check for the window names. Unfortunately none of these solutions are "Qt-Native".
supply a commandline argument only when started from Qt creator
If you use a library to scan commanline arguments this is probably the simplest solution. I usually use Boost Program Options (Google there). You could create a commandline argument like "--console-log" which specifies to put the logging output to the console. To set that option from within Qt Creator is documented here. This is probably the most "Qt-Native" solution. If you use Qt functions to parse the commandline, it is 100% Qt.
You can try IsDebuggerPresent or use only QDebug and check debug messages with debugview outside QT Creator.
You should google qInstallMessageHandler for more information.
But here goes the definitions:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QtGui>
#include <QtWidgets>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
static void myMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
// If you're running lots of threads you'll need to do some research to
// determine if you need to make this synchronized (i.e. locked)
if(staticTextEdit) {
staticTextEdit->appendPlainText(msg + "\n");
}
}
private slots:
void on_pushButton_clicked();
private:
// There's lots of different ways to do this ... this was the quickest way for me.
static QPlainTextEdit* staticTextEdit;
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
Here are the declarations:
#include "mainwindow.h"
#include "ui_mainwindow.h"
QPlainTextEdit* MainWindow::staticTextEdit = NULL;
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
staticTextEdit = ui->plainTextEdit;
qInstallMessageHandler(MainWindow::myMessageHandler);
}
MainWindow::~MainWindow()
{
delete ui;
}
// I'm using QtCreator to help create my slots. =).
void MainWindow::on_pushButton_clicked()
{
qDebug() << "CLICKED";
}
Here is a manual solution.
Define a macro in your .pro file....
# To turn on remove the comment marker '#'
# isEmpty(LAUNCH_FROM_IDE):LAUNCH_FROM_IDE = 1
!isEmpty(LAUNCH_FROM_IDE) {
DEFINES += APP_LAUNCH_FROM_IDE
}
And use in your header/source as needed...
#ifdef APP_LAUNCH_FROM_IDE
...
#endif
That's all
Not sure if this applies to the PC, but under OSX, when Qt Creator launches the application, it does it from the development build path; you can get the current launch path with:
QString expath = QCoreApplication::applicationDirPath();
Get that, dump it via qDebug(), and see where you're running from when launched from Qt. As long as that's not the location you run the application from when you're not launching it from within Qt, this should work.
I get this from the qDebug() when building and running in release mode from within Qt Creator:
"/Users/fyngyrz/build-iToolBox-Desktop_Qt_5_8_0_clang_64bit-Release/iToolBox.app/Contents/MacOS/iToolBox"
So for me, when building my app iToolBox I do the detection like this:
if (expath.indexOf("build-iToolBox-Desktop") != -1) // if we're running from inside Qt
{
}
else // we're not running from inside qt
{
}
Note1:
The release and build paths for Qt builds are different by default; so if you need this to work in both release and debug circumstances, you might have to do two checks of the path instead of one, depending on just what you're searching for.
Note 2:
If you incorporate this approach into your application, and the code will remain intact in the release build, be sure not to including anything in your search string that would incorporate any information you don't want to share, such as your real name which could be part of the path under some operating systems, depending on how you set up your user account.
Related
I have inherited a class called GraphicsPixmapItem from QGraphicsPixmapItem in order to override/create some mouse events. The problem is that I want to emit a signal after some calculations are performed, but it looks like it's not possible unless some hacks are performed, since this class is not a QObject.
To do so, I have tried to inherit the aformentioned new class from QObject as well, but I keep getting compiler errors.
My attemp:
Header file (graphicspixmapitem.h):
#ifndef GRAPHICSPIXMAPITEM_H
#define GRAPHICSPIXMAPITEM_H
#include <QObject>
#include <QGraphicsPixmapItem>
#include <QGraphicsSceneMouseEvent>
class GraphicsPixmapItem : public QObject, public QGraphicsPixmapItem
{
Q_OBJECT
public:
explicit GraphicsPixmapItem(QGraphicsItem *parent = 0);
virtual void mousePressEvent(QGraphicsSceneMouseEvent * mouseEvent);
virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent * mouseEvent);
signals:
void translationVector(QPointF info);
};
#endif // GRAPHICSPIXMAPITEM_H
Source file (graphicspixmapitem.cpp):
#include "graphicspixmapitem.h"
GraphicsPixmapItem::GraphicsPixmapItem(QGraphicsItem *parent) :
QGraphicsPixmapItem(parent)
{
}
void GraphicsPixmapItem::mousePressEvent(QGraphicsSceneMouseEvent * mouseEvent)
{
//Code
}
void GraphicsPixmapItem::mouseReleaseEvent(QGraphicsSceneMouseEvent * mouseEvent)
{
QPointF info;
//Code
emit(translationVector(info));
}
And I get the following linker errors:
undefined reference to `vtable for GraphicsPixmapItem'
undefined reference to
`GraphicsPixmapItem::translationVector(QPointF)'
Any clue about how to proceed accordingly?
Side note:
I am aware that QGraphicsObject may be a good alternative, but as discussed here, performance looks severely affected by the amount of signals that are emitted when operating with them, where most of them will not be used in my case. This is the reason why I prefer to create my own class with base QGraphicsItem, instead of QGraphicsObject.
Many thanks in advance.
It looks like the meta object compiler (moc) wasn't run over the code, or that moc's result wasn't included when linking.
Have you added graphicspixmapitem.h to qmake's HEADERS variable?
Have you re-run qmake and tried a clean build in general?
Is moc run on graphicspixmapitem.h? Check your compile log.
Is graphicspixmapitem_moc.o included when linking? Check your compile log.
I have finally found out the problem involving the linkage error. In this sense, I must give my thanks to Thomas McGuire for pointing out the key idea to look for the source of the problem.
The reason is that few days ago I attempted to subclass QGraphicsPixmapItem (for other purposes) with the exact same name than this one, namely, GraphicsPixmapItem (with header file graphicspixmapitem.h and source file graphicspixmapitem.cpp).
When I did that, I finally figured out that I could do things in a different way and I no longer needed that inherited subclass, hence I removed these files from the project. But doing this is a major mistake if you do not make sure to clean the project before removing the files from the project, because the files generated by qmake and moc (*.o, moc_*.cpp, moc_*.o) will remain in the build/debug directory unless you remove them by hand, because they will not be deleted by cleaning the project.
Therefore, it looks like in that situation, qmake detects that the files already exist and it does not generate the correct ones from the updated class, causing the linking error expounded above.
In summary, if you are going to delete some files from your project, make sure to clean it previously, especially if you are going to remove a class with the Q_OBJECT macro.
My task is to create a QSettings wrapper class (wrapping is mostly needed by QML) which I can reach everywhere from the model, too.
The obvious choice is a static global instance of this class. However the problem is with this approach is that it's destroyed after main, after QApplication is destroyed, thus giving me the following warning:
QApplication::qAppName: Please instantiate the QApplication object first
Here is a simplified, sample code showing a really simple wrapper, and the destruction phases:
#include <QCoreApplication>
#include <QDebug>
#include <QGlobalStatic>
#include <QSettings>
#include <QTimer>
class Settings: public QObject
{
public:
~Settings() { qDebug() << "~Settings"; }
QSettings settings;
};
Q_GLOBAL_STATIC(Settings, globalSettings)
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
QObject::connect(&app, &QCoreApplication::aboutToQuit, [](){qDebug() << "~QCoreApplication aboutToQuit";});
QObject::connect(&app, &QCoreApplication::aboutToQuit, [](){globalSettings->settings.setValue("Hi", 2);});
QObject::connect(&app, &QCoreApplication::destroyed, [](){qDebug() << "~QCoreApplication destroyed";});
QTimer::singleShot(0, &app, SLOT(quit()));
return app.exec();
}
It prints out the following:
~QCoreApplication aboutToQuit
~QCoreApplication destroyed
~Settings
QApplication::qAppName: Please instantiate the QApplication object first
My question is: providing, in my program QSettings is used after QCoreApplication::aboutToQuit is emitted but before QCoreApplication::destroyed, how can I avoid this warning?
Using QSettings
I've used QSettings in pretty much every project I've ever made. Here is the pattern that I tend to use it:
in main.cpp
#include <QSettings>
//...
// Then in main(), after QApplication is instantiated, but before any settings are accessed
QSettings::setDefaultFormat(QSettings::IniFormat);
QApplication::setOrganizationName("MyOrg");
QApplication::setApplicationName("MyApp"):
Then anytime you are about to access QSettings, you just do this:
QSettings s;
s.value(// reading a value
s.setValue(// writing a value
Everything gets saved in the User Scope in an INI text file. It will be located in Windows under C:/Users/<username>/AppData/Roaming/MyOrg/MyApp.ini.
This usage of QSettings (IMHO) is very clean, doesn't require global variables or static references and is very fast and efficient. And it is very readable.
Now to be able to have things load settings at the right times, and not get the errors you mentioned in your question, see the initial example in the links below:
http://doc.qt.io/qt-5/qsettings.html#restoring-the-state-of-a-gui-application
http://doc.qt.io/qt-5/qtwidgets-mainwindows-application-example.html
It works much better in the timeline of a Qt application and works great. I tend to make a readSettings and writeSettings for most of my GUI classes and for a number of my backend classes. readSettings happens when the widget has its showEvent or constructor happen and the writeSettings happens in the closeEvent. Also if I have a dedicated settings dialog, I emit a signal to have any affected classes to readSettings, right after the settings dialog writes those specific settings.
If you use the QML port of QSettings, it also uses the Organization name and Application name and the default format of QSettings to pick its filename and location.
http://doc.qt.io/qt-5/qml-qt-labs-settings-settings.html
I believe the default functionality of that QML component is just to read the setting when the component is created, and to write the setting whenever QML changes it. So to change it from C++ and have it recognized by QML, you should probably use the standard QML/C++ methods out there such as:
http://doc.qt.io/qt-5/qtqml-cppintegration-topic.html
And lastly if I am planning on installing defaults for a program that are decided for a build and I don't want to hardcode them, I hand write an INI file and have the installer place it in the system scope location: C:/ProgramData/MyOrg/MyApp.ini
And in the case that the settings of your program are more complex than what you want to store in an INI file, I would look into using QJson, and the SaveGame example.
Hope that helps.
I am just getting started in Qt, and trying to get a simplified, working example of the model-view-controller design pattern.
So far, I have been able to use signals and slots to connect basic widgets like push buttons to a QLabel, and have the view be modified as the push button is clicked/released. See code below for a working example of that (implemented in the MainWindow class).
I am trying to define a class, in this case, Game, which is going to be my model. I want Game to have all of the data and business rules of my entire application. I do not require that Game be anything Qt specific--it very well could be generic C++. However, in the code below, it does have some Qt-specific code to implement a QTimer which is useful for the purposes of this example.
I am trying to achieve two things in this example:
I want to have a model which is able to generate some sort of event within itself, like incrementing a variable value over the passage of time, and then ultimately see that change somehow reflected in the view. Or better yet, the timeout() of the QTimer could simply be the signal that is connected to some slot, that slot being some event that takes place within the model. Using the code shown below, the reflection in the view would be the setting of label_1 (part of the MainWindow class) to display one of the images already stored in imageOn or imageOff (also part of the MainWindow class).
I want to have the push button associated with the on_pushButton_clicked() and on_pushButton_pressed() slots be able to modify some value stored within the model. Then, coming full circle with item 1, have that update of the model be reflected in the view.
If my terminology thus far is incorrect or inconsistent with Qt terminology of MVC design pattern, forgive me. I would welcome any clarification on that. Also, if the example code I have provided is too convoluted for exemplifying the MVC design pattern in Qt, I am more than willing to wipe the slate clean and start with a more appropriate example. All I am trying to do is get started with Qt and MVC, but in a way that deals with more complex data types.
I am trying to develop an example in which I can handle a model and class such as Game which is potentially complex--not a simple list of QStrings or something guaranteed to be more straight-forward. When I browsed through the Qt documentation related to MVC, I came across a lot of examples that used the setModel() function to try and make the connections I am essentially outlining in list items 1 and 2. The problem was that I could not see a way of using that exact approach with a more complex data-type like Game which might be the entire data model for a complete application (I know Game is not complex in this example, but it could be eventually). I need something that is scalable and extensible, something that would work for an entire application. If those setModel()-type functions are suitable for this--which they very likely could be, I just could not figure it out on my own--I would like to know how to implement those in this example dealing with QLabel and images.
Code:
game.h
#ifndef GAME_H
#define GAME_H
#include <QtCore>
class Game : public QObject {
Q_OBJECT
public:
Game();
void timed_job();
private:
QTimer *timer;
};
#endif // GAME_H
game.cpp
#include "game.h"
#include <QtCore>
Game::Game() {
}
void Game::timed_job() {
timer = new QTimer(this);
timer->start(1000);
//connect(timer, SIGNAL(timeout()), this, SLOT(flip()));
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow {
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void on_pushButton_clicked();
void on_pushButton_pressed();
private:
Ui::MainWindow *ui;
QImage imageOn, imageOff;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include <QImage>
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow) {
imageOn.load(":/Files/On.jpg");
imageOff.load(":/Files/Off.jpg");
ui->setupUi(this);
}
MainWindow::~MainWindow() {
delete ui;
}
void MainWindow::on_pushButton_clicked() {
ui->label_1->setPixmap(QPixmap::fromImage(imageOff));
}
void MainWindow::on_pushButton_pressed() {
ui->label_1->setPixmap(QPixmap::fromImage(imageOn));
}
main.cpp
#include <QtGui/QApplication>
#include <QLabel>
#include "mainwindow.h"
#include "game.h"
int main(int argc, char *argv[]) {
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
A "controller" in Qt could technically be represented by a separate QObject subclass, containing just slots. And you would wire this between your model and view.
But normally what I do (and see) is to just make your model contain business logic, and your view subclass contain methods for handling it's user interactions. The closest I get to the controller concept is when I have my QMainWindow (or dialog) class that represents the application, and has a bunch of SLOTS on it. These slots get wired in to the private UI members signals to connect them together.
Example: Your main window has a model, a view, and a push button. In the init for the main window, I would set the model in the view, and connect the push button "clicked" to a slot on my window refreshData(). This slot would then call the "update" method on the model, which will automatically propagate to the view. The main window thus acts like a controller.
What you would want to do is to make some type of QAbstractItemModel or QStandardItemModel that represents your data and does what you want to update that data (a timer like you suggested). Any view connected to the model will be able to see it because of the standard interface. You can also just make a separate timer that places data into an existing QStandardItemModel
A note about custom QAbstractItemModel classes
As pointed out by #hyde, jumping into a custom model can be a challenge if you try and do it first, before getting a good understanding of the existing concrete model classes. Here is what I recommend doing:
Get familiar with the convenience widgets (QListWidget, QTableWidget, QTreeWidget)
Then try using a QStandardItemModel with a QListView/QTableView
Then work with QTreeView
Finally, when you really need very custom modeling for your existing data structures, you can work on subclassing QAbstractItemModel to make it use your own internal structure.
nearly searching for hours I became more confused about the Multithreading concept and I need help understanding and implementing it. After searching I have come to the following implementation
main.cpp
#include <QtGui/QApplication>
#include "mainwindow.h"
#include <mythread1.h>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
mythread abc;
abc.start();
abc.wait();
return a.exec();
}
In above code mythread.h is my header file which I created for multithreading and below is my code of mythread1.h
mythread1.h
#ifndef MYTHREAD1_H
#define MYTHREAD1_H
#include <QtGui>
#include <windows.h>
class mythread : public QThread
{
public:
void run();
};
void mythread::run()
{
}
#endif // MYTHREAD_H
Now my questions are
I have defined only one function run() and when the thread is initialized how compiler determines it has to execute run() function and what it does when it has multiple functions, I got this question because in main.cpp I just typed abc.start(); and didn't specify what to execute?
Inside mythread1.h and in run function I made a infinite loop using while(0<1) and ran the program and to my surprise I was just presented with white screen with 100% CPU usage(not a surprise), but it should run concurrently without interfering with main thread right? then why this is happening?
I then used QFile::copy("pathtomytargetfile","targetpath"); inside the run function inside in mythread1.cpp but that didn't work :O and it didn't copy that file but when i connected it with Push button in main thread then it got successfully copied, why this happened?
Does anyone know a simpler way to implement multithreading?
Thank you
First of all: run method should be protected!
Secondly, what do you mean by "I have defined only one function run()". You defined method, not function. abc.start() means that abc instance of mythread will start and use it's entry point method void run(). You can't declare more than one method with same signature. And if you wonder how it calls your run() instead of QThread::run() then you need to read something about virtual methods in C++
Ad. 3: How can we tell why your file didn't copy? Check what errors QFile provides you. Change your code something like that:
QFile f("pathtomytargetfile");
if( ! f.copy("targetpath") )
{
qDebug() << f.errorString();
}
It will provide you some usefull info
My answer might confuse you even more, but the following links are worth reading in my opinion:
This is an article by the engineer who introduced the QThread class. He apologizes for suggesting that inheriting from QThread is the way to go.
This article shows you, how you should do it (strictly speaking -- inheriting from QThread will work as well, it just is not as nice design-wise).
On this page you can find an overview of multithreading techniques that Qt offers and some help deciding which one you should use for your specific problem.
HTH
I started writing some tests with Qt's unit testing system.
How do you usually organize the tests? It is one test class per one module class, or do you test the whole module with a single test class? Qt docs suggest to follow the former strategy.
I want to write tests for a module. The module provides only one class that is going to be used by the module user, but there is a lot of logic abstracted in other classes, which I would also like to test, besides testing the public class.
The problem is that Qt's proposed way to run tests involved the QTEST_MAIN macro:
QTEST_MAIN(TestClass)
#include "test_class.moc"
and eventually one test program is capable of testing just one test class. And it kinda sucks to create test projects for every single class in the module.
Of course, one could take a look at the QTEST_MAIN macro, rewrite it, and run other test classes. But is there something, that works out of the box?
So far I do it by hand:
#include "one.h"
#include "two.h"
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
TestOne one;
QTest::qExec(&one, argc, argv);
TestOne two;
QTest::qExec(&two, argc, argv);
}
Related to the answer posted by #cjhuitt
This is an example that removes the need of manually calling each test object
I TRY TO AVOID THINGS LIKE THIS:
MyTestClass1 t1; t1.run();
MyTestClass2 t2; t2.run();
//etc...
My solution is to let the test objects inherit from a base class that adds itself to a static list
The main program then executes all the test objects in that list. In that way, none of the supporting framework code needs to be changed. The only things that change are the test classes themselves.
Here is how i do it:
qtestsuite.h - base class for the test objects
#ifndef QTESTSUITE_H
#define QTESTSUITE_H
#include <QObject>
#include <vector>
class QTestSuite : public QObject
{
Q_OBJECT
public:
static std::vector<QObject*> m_suites;
public:
explicit QTestSuite();
};
#endif // QTESTSUITE_H
qtestsuite.cpp
#include "qtestsuite.h"
#include <iostream>
std::vector<QObject*> QTestSuite::m_suites;
QTestSuite::QTestSuite() : QObject()
{
m_suites.push_back(this);
}
testall.cpp - runs the tests
#include "qtestsuite.h"
#include <QtTest/QtTest>
#include <iostream>
int main(int, char**)
{
int failedSuitesCount = 0;
std::vector<QObject*>::iterator iSuite;
for (iSuite = QTestSuite::m_suites.begin(); iSuite != QTestSuite::m_suites.end(); iSuite++)
{
int result = QTest::qExec(*iSuite);
if (result != 0)
{
failedSuitesCount++;
}
}
return failedSuitesCount;
}
mytestsuite1.cpp - an example test object, create more of these
#include "qtestsuite.h"
#include <QtTest/QtTest>
class MyTestSuite1: public QTestSuite
{
Q_OBJECT
private slots:
void aTestFunction();
void anotherTestFunction();
};
void MyTestSuite1::aTestFunction()
{
QString str = "Hello";
QVERIFY(str.toUpper() == "this will fail");
}
void MyTestSuite1::anotherTestFunction()
{
QString str = "Goodbye";
QVERIFY(str.toUpper() == "GOODBYE");
}
static MyTestSuite1 instance; //This is where this particular test is instantiated, and thus added to the static list of test suites
#include "mytestsuite1.moc"
also, to create the .pro file
qmake -project "CONFIG += qtestlib"
In our setup with QTest, we did a few things to make it nicer.
Define a subclass of QObject that is used as a base class for any new unit-test class.
In the constructor for that class, we add the instance of the test to a static list of tests, and in the destructor we remove it.
We then have a static function that loops through the tests and runs them using QTest::qExec(). (We accumulate the values returned each time, and return that from our function.)
main() calls this function, and returns the result as the success/failure.
Finally, in the compilation unit of the specific test itself, we usually include a static instance of that class.
This setup means that the class will be instantiated before main() is run, so it will be added to the list of classes to test when main runs. The framework requires that you just need to inherit your class properly, and instantiate a static instance if you always want it run.
We also occasionally create other optional tests, that are added based on command line switches.
Yeah, QTest forces bit strange test structure and is generally inferior to Google Test/Mock Framework. For one project I'm forced to use QTest (client requirement), and here's how I use it:
I compile all test together as a subdir template project
To make creating new tests easier, I share a lot of project configuration by using common.pri file I include in every test .pro file
If possible I share the object files directory to speed up compilation
I run them all using a batch+awk+sed script.
Setting up this four points is very easy and makes usage of QTest almost pleasant. Do you have some problems with running multiple tests that are not solved by the config described above?
PS: running tests the way you do, i.e. calling multiple QTest::qExec causes problems with -o command line switch - you'll get only results for the last tested class.
Usually I organize tests with one test executable per class under test.
and eventually one test program is
capable of testing just one test
class.
This is a good thing. It isolates your tests from each other, preventing things like a crash in one test from blocking all your other tests. That crash could be caused by a common component in several classes under test. The pattern of the failures would then tip you off to the underlying origin of the problem. Basically, you have better diagnostic information for failures if your tests are independent of each other.
Make it easy to set up multiple executables and run each test separately. Use a test runner to spawn off all the test processes.
Update:
I've changed my mind on this somewhat. Once you have a big program with lots of tests, linking hundreds of test executables becomes very slow. My new preference is to put all the tests for a library into an executable and choosing which tests to invoke using command-line arguments passed to the test executable.
That cuts down the number of executables from hundreds to dozens, but retains the advantages of running tests separately.