I want to use QThreadSynchronizer in my class, like so
#ifndef _MULTIWATCHER
#define _MULTIWATCHER
#include <QThread>
#include <QFutureSynchronizer>
#include "globals.h"
class MultiWatcher : public QThread
{
Q_OBJECT
public:
signals:
void allDone();
public:
void run() override;
QFutureSynchronizer<FocusResult> _sync;
};
#endif
However, when I try to build this I get the following linking errors
1>C:\Qt\5.7\msvc2015_64\include\QtCore/qvector.h(134): error C2182: 'at':
illegal use of type 'void'
1>C:\Qt\5.7\msvc2015_64\include\QtCore/qvector.h(135): error C2182: '[]':
illegal use of type 'void'
1>C:\Qt\5.7\msvc2015_64\include\QtCore/qvector.h(136): error C2182: '[]':
illegal use of type 'void'
etc ...
Actually I get the same errors if I comment out the entire class (its also the same if QThreadSynchronizer is replaced by QFuture) and just try to include the two include files, as if QThread and QFuture/QThreadSynchronizer are incompatible with each other. So the following also doesn't link!
#ifndef _MULTIWATCHER
#define _MULTIWATCHER
#include <QThread>
#include <QFuture>
#endif
Any ideas?
The problem was solved by changing the "Common Language RunTime Support" option from "Common Language RunTime Support /clr" to "No Common Language RunTime Support" for the moc_multiwatcher.cpp file that QT generates. These files are in "Generated Files"->Debug section of the Solution Browser, the clr setting for this file can be accessed by right clicking on it and going to properties. I hope this is useful for other people having strange linking errors in their c++/clr/QT visual studio projects.
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.
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.
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 am learning GUI coding with Qt and hope to clear up some confusion on my part. When I create a dialog with Qt Creator it creates code for me like this...
#ifndef LISTDIALOG_H
#define LISTDIALOG_H
#include <QDialog>
#include "ui_listdialog.h" //Q1:Why was this auto paced in cpp file instead of h file?
//Q2: This is what I'm really confused about.
//Is Ui namespace wrapping ui_listdialog class or the ListDialog class?
namespace Ui {
class ListDialog;
}
class ListDialog : public QDialog
{
Q_OBJECT
public:
explicit ListDialog(QWidget *parent = 0); //Q3: Why is this constructor explicit?
~ListDialog();
//CUSTOM FUNCTIONALITY NOT ADDED BY CREATOR (IGNORE FOR MY POST)
private slots:
void addItem();
void editItem();
void deleteItem();
//END CUSTOM FUNCTIONALITY
private:
Ui::ListDialog *ui; //Placed on heap instead of stack.
};
#endif // LISTDIALOG_H
There are things in the above code that differ from my 3 Qt books (all 3 out of date and ignore Creator).
My main confusion comes from Q2. Is "Ui" wrapping "ui_listdialog.h" or the class I have posted here ( class ListDialog )? The syntax seems to imply to me that it is wrapping the latter but I feel it must be actually wrapping the ui_listdialog.h class instead. Very confused about this. Can someone explain this clearly?
I also don't understand why the constructor was made explicit by Creator. I have not seen that in any of the 3 books.
Q1. The #include is placed in the .cpp to avoid too many dependencies in the header file. This shortens compilation time, because if you change the dialog, the only thing you have to recompile is the .cpp and not everything that includes your header file. In general, if a forward declaration of a class is enough (i.e. you only have a pointer or a reference to it in your class), then it's better not to #include the class's definition.
Q2. Ui is a namespace that contains a different class called ListDialog. You can open the header file and see the definition of this other class. A bit confusing until you get used to it.
Q3. It's a good habit to use the explicit keyword with constructors that take a single parameter. Otherwise the constructor can also be used as an automatic conversion operator, and this can cause problems if you're not aware of it. For example, if you have a function that takes a ListDialog parameter, and you pass a QWidget * parameter, it may call the constructor when in fact you want the compiler to shout (invalid parameter).
The ui_listdialog.h contains implementation to generate your user interface based on Qt Designer. It isn't necessary when declaring the class -- that's why the file was #included in the .cpp (Q1). Without the ui_listdialog.h in the header, the class declaration is necessary (Q2).
As for Q3, it's probably there to make you use the constructor syntax. Else, you could write misleading statements like
ListDialog dialog = parentDialog ;
So basically, I am making a very simple Qt app to help me along as I learn OpenGL. The idea
is that I have two windows, one is a GL context (GLWidget, derived from QGLWidget) and the other is a simple GUI with a couple of progress bars and a text area.
I can get the app to compile and run, and everything is beautiful UNTIL I tried to connect signals and slot between the two windows. I have read through the docs on QGLWidget, the official tutorial on signals and slots, and the documentation for int connect().
To illustrate: my main.cpp file:
#include <QApplication>
#include <QObject>
#include "glwidget.h"
#include "mainwindow.h"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
MainWindow *mWindow = new MainWindow();
GLWidget *gl = new GLWidget();
//If this line is commented out, the program compiles and runs
connect(gl, SIGNAL(fpsReport(float)), mWindow, SLOT(updateFPS(float));
mWindow->show();
gl->show();
return app.exec();
}
The specific compiler errors I am getting are:
In function 'int qMain(int, char**)':
invalid conversion from 'GLWidget*' to 'SOCKET'
cannot convert 'const char*' to 'const sockaddr*' for argument '2' to 'int
connect(SOCKET, const sockaddr*, int)'
Not sure if this is relevant, but I'm using Qt Creator 2.0.1, based on Qt 4.7.0 (32 bit).
Running 32-bit Windows 7 Ultimate.
connect is a static member of QObject. When used outside of a QObject context, you need to specify the scope as such :
QObject::connect(gl, SIGNAL(fpsReport(float)), mWindow, SLOT(updateFPS(float));
Otherwise, the compiler tries to call another function called connect() which resides in the global scope, and obviously, this other function uses different parameters.
You're trying to use the connect function from windows socket API. Try:
QObject::connect(gl, SIGNAL(fpsReport(float)), mWindow, SLOT(updateFPS(float));