I am new at Qt (and c++). I have a simple question:
What is wrong?
#include <QCoreApplication>
#include <QtNetwork/QLocalServer>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QLocalServer* x = new QLocalServer(this);
return a.exec();
}
Thank for advice.
Your problem is this (pun intended):
QLocalServer* x = new QLocalServer(this);
this is not valid outside non-static class member functions. main() is not a member function, and thus this doesn't exist. You can pass NULL pointer instead, to signify that the object shall have no parent:
QLocalServer* x = new QLocalServer(NULL);
Don't forget to add the network module in your project file's QT variable. For example:
QT += OTHER_MODULES_YOU_USE_HERE network
Related
I have a very strange problem while trying to run a QProcess in a class HmiApplication, which is derived from QApplication.
The application throws a SIGSEGV in line 6 of main.cpp. This occurs only if line 11 of hmiapplication.cpp is commented out (If I don't qDebug() the stdout of the QProcess).
For the sake of simplicity and clarity, I didn't handle any return values while creating the QProcess.
main.cpp
#include "hmiapplication.h"
int main(int argc, char **argv)
{
HmiApplication hmi(argc, argv);
return hmi.exec(); // LINE 6 - SIGSEGV
}
hmiapplication.h
#ifndef HMIAPPLICATION_H
#define HMIAPPLICATION_H
#include <QApplication>
#include <QProcess>
class HmiApplication : public QApplication
{
Q_OBJECT
public:
HmiApplication(int argc, char **argv);
virtual ~HmiApplication();
private:
QProcess *macFinder = nullptr;
};
#endif // HMIAPPLICATION_H
hmiapplication.cpp
#include "hmiapplication.h"
HmiApplication::HmiApplication(int argc, char **argv) : QApplication(argc, argv)
{
macFinder = new QProcess(this);
macFinder->start("arping", QStringList() << "-c 2" << "192.168.1.1");
macFinder->waitForReadyRead();
QString ret(macFinder->readAllStandardOutput());
ret = ret.mid(ret.indexOf('[') + 1, 17);
qDebug() << ret; // LINE 11
}
HmiApplication::~HmiApplication()
{
}
EDIT:
If I add QVector<Camera*> cameras; to the header and
for(quint8 i = 0; i < 10; i++) {
Camera *cam = new Camera(i);
cameras.append(cam);
}
to the source file, it doesn't matter whether or not I remove the qDebug() line and will throw a segmentation fault in both cases.
Camera is a derived class of QLabel and is perfectly working without the QProcess mentionened above.
The QApplication constructor accepts its first parameter by reference...
QApplication::QApplication(int &argc, char **argv)
With the documentation also warning that...
The data referred to by argc and argv must stay valid for the entire
lifetime of the QApplication object. In addition, argc must be greater
than zero and argv must contain at least one valid character string.
However, you pass argc by value to the HmiApplication. Hence the QApplication constructor receives a non-const reference to the local copy which will go out of scope at the end of the HmiApplication ctor leading to undefined behaviour later on.
Change the signature of your constructor to...
HmiApplication::HmiApplication(int &argc, char **argv)
I am building a qt application in which i am have to access ui elements. but i am getting error as
invalid use of member 'foo::ui' in static member function
The code is big so cant add here.
Declaration of ui
private:
Ui::foo *ui;
Initialization in Constructor
foo::foo(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::foo)
{
ui->setupUi(this);
}
Accessing in static function where it is giving error.
ui->fp->setText("Some Text");
Static function declaration.
static I eventCallback(PVOID i_pv_context,
T_xyz i_i_command,
PVOID i_pv_param);
main code
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
BarrierInterfaceModule w;
w.show();
return a.exec();
}
I have looked on Internet but did not get solution. please let me know if there is a way around.let me know if you need any more info Thanks in advance
I'm aware of two possible solutions:
Use a singleton class for foo. This method only works if you need only one instantiation of foo, which is probably the case because it is a QMainWindow. Now, you can set the text as follows: getInstance()->ui->fp->setText("Some Text");
Often callback function are able to pass a pointer to user supplied data, but this depends on the library you are using.
I want to use git from an Qt application. So far, I use QProcess, but I do not want to use that. So I found libgit2.
This works as expected:
#include <QApplication>
#include "git2.h"
int main(int argc, char* argv[])
{
git_repository* repo = 0;
git_clone(&repo, "/path_to/barerep", "/path_to/test_clone", NULL);
git_repository_free(repo);
repo = 0;
}
But here, git_clone crashes.
int main(int argc, char* argv[])
{
QApplication a(argc, argv);
git_repository* repo = 0;
git_clone(&repo, "/path_to/barerep", "/path_to/test_clone", NULL);
git_repository_free(repo);
repo = 0;
return a.exec();
}
The error is:
*** Error in `/path_to/gittest': free(): invalid pointer: 0x09d53a88 ***
Any suggestions? Of course, omitting QApplication is not an alternative. The same error occurs without return a.exec().
Note: Actually, there is a class GitRepository with a method clone(const QString & url) (the path is stored somewhere in the class).
Again, this works
int main(int argc, char* argv[])
{
GitRepository g;
g.clone("path_to/barerep");
}
But this does not. (QObject!)
int main(int argc, char* argv[])
{
QObject(); // <--
GitRepository g;
g.clone("path_to/barerep");
}
does not.
bool GitRepository::clone(const QString & url)
{
git_repository* repo = 0;
git_clone(&repo, CSTR(url), CSTR(path()), NULL);
git_repository_free(repo);
repo = 0;
//loadFromTempDir();
return true;
}
Replacing QApplication by QObject in the first example suppresses the error.
You need to call git_libgit2_init() before calling any other libgit2 functions. As the documentation says:
This function must the called before any other libgit2 function in order to set up global state and threading.
These kind of errors are really hard to find. I also had problems mixing Qt libraries with other libraries. The trick is to organize your code in a way that there is only one library included in one compilation unit.
Create a class, which wraps around libgit2, and only include the libgit2 headers in the cpp file of this class. Do not include any qt headers in the same file.
Only refer to libgit throw your wrapper. Sure it seems like a lot of work, but as a result your code will be cleaner, and these misterious errors will be gone.
I have just started developing using QtGUI and I have checked out some tutorials and documentation, and by what I've read this should work.
#define CONNECT QObject::connect
void test();
QPushButton *lpTestBtn;
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QtProject w;
w.show();
lpTestBtn = w.window()->findChild<QPushButton*>("TestBtn");
CONNECT(lpTestBtn, SIGNAL(clicked()),qApp,SLOT(test()));
return a.exec();
}
void test()
{
lpTestBtn->setText("Hi");
}
But test() never gets called. Also, lpTestBtn is not null and is found correctly.
I have tried the following changes
CONNECT(lpTestBtn, SIGNAL(clicked()),qApp->activeWindow(),SLOT(test()));
CONNECT(lpTestBtn, SIGNAL(clicked()),w.window(),SLOT(test()));
I know I can just do QtProject::on_TestBtn_clicked(); but I'd like to get it working using CONNECT,SIGNAL and SLOT.
The test function in your code is not a slot, nor does it belong to the Q(Core)Application class as you seem to have used it.
The best would be is to move that one line in the test function to the connection with the lambda syntax. This will require C++11 support, but that is in quite common use these days.
You would use the new shiny signal-slot syntax. This would spare you some headache for runtime issues in the future because they would appear at compilation-time.
Therefore, you would write something like this:
main.cpp
#include <QMainWindow>
#include <QApplication>
#include <QPushButton>
int main(int argc, char **argv)
{
QApplication a(argc, argv);
// Replace it with "QtProject".
QMainWindow w;
w.show();
QPushButton * lpTestBtn = w.window()->findChild<QPushButton*>("TestBtn");
QObject::connect(lpTestBtn, &QPushButton::clicked, [=]() {
lpTestBtn->setText("Hi");
});
return a.exec();
}
main.pro
TEMPLATE = app
TARGET = main
QT += widgets
CONFIG += c++11
SOURCES += main.cpp
Build and Run
qmake && make && ./main
Please also note that it is bad idea to create a global pointer for a QPushButton object. It not only leaks the memory, but you could have other issues, too.
1) QApplication doesn't have a test() slot in it. You need to make your own class, inheriting QApplication, and give that class a test() slot. What you've done is create a regular function, which won't help.
2) You didn't check the return value of connect, which means you didn't see that it was giving you an error, which would probably have given you some clues.
You can connect signals to the slots which are in classes derived from QObject so meta compiler can deduce slot calls. But your test() is global function. You have to put your slot function inside a class that derives from QObject and supports Q_OBJECT macro or define a lambda function ( with C++11 support) as Laszlo Papp showed.
Example:
// testwrapper.h
class TestWrapper : public QObject
{
Q_OBJECT
//...
public slots:
void test();
};
// main.cpp
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QtProject w;
w.show();
QPushButton * lpTestBtn = w.window()->findChild<QPushButton*>("TestBtn");
TestWrapper tw;
CONNECT( lpTestBtn, SIGNAL( clicked()),tw,SLOT( test()));
return a.exec();
}
I need to exec() a QApplication in a thread that is not main (my GUIs must be plugins that can be dynamically loaded and unloaded at runtime, so I have no access to the main thread). Does anyone know of a (relatively) painless way to hack around Qt's restriction against starting QApplication outside of main?
I'm developing in Linux with Qt4 in C++ using gcc4.3.4.
You can start a QApplication in a PThread as below
//main.cpp
#include <iostream>
#include "appthread.h"
int main(int argc, char *argv[]) {
InputArgs args = {argc, argv};
StartAppThread(args);
sleep(10);
return 0;
}
//appthread.h
struct InputArgs{
int argc;
char **argv;
};
void StartAppThread(InputArgs &);
//appthread.cpp
#include <QApplication>
#include <QMainWindow>
#include <QPushButton>
#include "appthread.h"
#include <pthread.h>
void *StartQAppThread(void *threadArg) {
InputArgs *args = (struct InputArgs*) threadArg;
QApplication app(args->argc, args->argv);
QMainWindow w;
w.show();
w.setCentralWidget(new QPushButton("NewButton"));
app.exec();
pthread_exit(NULL);
}
void StartAppThread(InputArgs &args) {
pthread_t thread1;
int rc = pthread_create(&thread1, NULL, StartQAppThread, (void*)&args);
}
If you are using QThread then you already have normal Qt event loop and can just run exec() inside QThread::run() function. While you can't work with GUI objects outside of the main thread you still can interact with them through queued signal/slot connections. Maybe you can try to store pointer to the main thread QThread object and call QObject::moveToThread() to move your GUI objects to the main thread instead of moving QApplication into another thread.
I think it's not really good idea to try to go against toolkit with different kind of hacks and kluges.
Ok, I got something that works! It's not pretty, but it definitely does the job.
Create a QMainWindow derivative with all of your actual GUI code in it and overload the event() function of this class to call this->show()
Create a class (let's call it Runner) which will hold a pointer to your QMainWindow derivative, and give it a run function.
In the Runner::Runner(), start up a thread which will call Runner::run()
In Runner::run() (which is now running in it's own thread) construct a QApplication, and an instantiation of your QMainWindow derivative. Call the exec() function of the QApplication.
Now, when you want to start up your GUI, just post any event to your QMainWindow derivative, and it will show itself!
This solution seems to work very well in Linux, although it really seems to be exploiting some loophole in Qt and may not work on other platforms. Definitely easier than patching Qt though.
Patch Qt, I guess and remove the main thread check, and test if that works for you.
According to
http://bugreports.qt-project.org/browse/QTBUG-7393
that won't work on OS X/Cocoa though, as Cocoa assumes the first thread spawned to be the main/UI thread.
Adding my 2 cents with a fancy lambda and C++ threads:
#include "mainwindow.h"
#include <QApplication>
#include <thread>
int main(int argc, char *argv[])
{
std::thread t1
(
[&]
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
);
t1.join();
}
Here Mainwindow can be your QMainWindow.
A good solution is found in: git#github.com:midjji/convenient_multithreaded_qt_gui.git
then its just e.g.
run_in_gui_thread(new RunEventImpl([](){
QMainWindow* window=new QMainWindow();
window->show();
}));
or whatever code you wish to run in the gui thread.
callable from any thread, at any time, while taking care of setting things up for you in the bg.