QML start external program: use QProcess fail build [duplicate] - qt

I wrote a little program with a my own class within the main.cpp. Here the code:
#include <QApplication>
#include <QPushButton>
#include <QLabel>
class MyWidget : public QWidget {
//Q_OBJECT
public:
MyWidget(QWidget* parent = 0);
QLabel* label;
QString string;
signals:
public slots:
void setTextLabel();
};
void MyWidget::setTextLabel() {
label->setText("Test");
}
MyWidget::MyWidget(QWidget* parent)
: QWidget(parent) {
}
int main(int argc, char** argv) {
QApplication app(argc, argv);
MyWidget widget;
widget.show();
return app.exec();
}
it seems work but not "completely". My slot doens't work. I suppose i have to put Q_OBJECT. BUT, doing so, I got a list of errors, like this:
undefined reference to `vtable for MyWidget'
........................................
collect2: error: ld returned 1 exit status
make: *** [mywidget] Error 1
I can I manage that? Where the problem?

Signals and slots in Qt are managed through the moc: meta object compiler. Basically, the moc generates additional C++ code for each class containing the Q_OBJECT macro in order to implement effectively the signals and slots mechanisms. The additional code is then linked to the original class declaration.
The problem here is that your class is declared in main.cpp: this conflicts with how the moc is working with your code. You should declare your class in a separate header.
More about the moc
Edit: as hyde pointed, an alternative is to include in your cpp the file generated by the moc: Why is important to include “.moc” file at end of a Qt Source code file?

just append the line #include"main.moc" to your cpp source file should be enough.
More information:
Why is important to include ".moc" file at end of a Qt Source code file?

Related

gcc compiles my Qt class with vtable undefined

I cannot get rid of the error "Undefined reference to vtable" when compiling my Linux desktop application.
I did find the thread
Undefined reference to vtable
I have a
set(CMAKE_AUTOMOC ON)
in my CMakeLists.txt
but I receive
AutoMoc warning
---------------
"SRC:/QtGUI/BASIC/SimulatorWindowBasic.cpp"
includes the moc file "SimulatorWindowBasic.moc", but does not contain a Q_OBJECT, Q_GADGET, Q_GADGET_EXPORT, Q_NAMESPACE or Q_NAMESPACE_EXPORT macro.
despite that my definition contains
a Q_Object.
At the end of build, I receive the feared message
/usr/bin/ld: CMakeFiles/Basic_GUI.dir/Basic_GUI.cpp.o: in function `main':
/Myhome/main/BASIC/Basic_GUI.cpp:6: undefined reference to `SimulatorWindowBasic::SimulatorWindowBasic(int, char**, QWidget*)'
/usr/bin/ld: CMakeFiles/Basic_GUI.dir/Basic_GUI.cpp.o: in function `SimulatorWindowBasic::~SimulatorWindowBasic()':
What do I wrong?
Below I show my relevant sources.
(in my previous install using Qt5 and Ubuntu 20.04
I did not experience this issue. The present install uses Ubuntu 22.04 and Qt 6.4.2)
#ifndef SimulatorWindowBasic_H
#define SimulatorWindowBasic_H
#include <QMainWindow>
namespace Ui {
class SimulatorWindowBasic;
}
class SimulatorWindowBasic : public QMainWindow
{
Q_OBJECT
public:
explicit SimulatorWindowBasic(int argc, char **argv, QWidget *parent = 0);
virtual ~SimulatorWindowBasic();
protected:
Ui::SimulatorWindowBasic *ui;
};
#endif // SimulatorWindowBasic_H
and
#include "SimulatorWindowBasic.moc"
#include "SimulatorWindowBasic.h"
#include "uiSimulatorWindowBasic.h"
SimulatorWindowBasic::SimulatorWindowBasic(int argc, char **argv, QWidget *parent) :
QMainWindow(parent),
ui(new Ui::SimulatorWindowBasic)
{
ui->setupUi(this); // This creates the basic splitters
}
SimulatorWindowBasic::~SimulatorWindowBasic
{
}
You have to include "moc_SimulatorWindowBasic.cpp" because you want to have moc run on a header (and not on your source) as described in the cmake documentation

Qt class MyButton when use Q_PRIVATE_SLOT, the .h file compile error: undefined MyButtonPrivate

https://www.dvratil.cz/2019/11/q-private-slot-with-new-connect-syntax/
#include <QPushButton>
#include <memory>
class MyButtonPrivate;
class MyButton : public QPushButton {
Q_OBJECT
public:
explicit MyButton(QWidget* parent);
~MyButton() noexcept override;
private:
std::unique_ptr<MyButtonPrivate> const d_ptr;
Q_DECLARE_PRIVATE(MyButton);
Q_PRIVATE_SLOT(d_func(), void onClicked(bool));
};
this is the .h file, compile error: undefined MyButtonPrivate.
truely, the moc_MyButton.cpp(auto generated by compiler) doesnot include the MyButtonPrivate.
then what's wrong, and how to solve?
I'm not sure why it's an error, but according to https://forum.qt.io/topic/61295/solved-what-is-the-usage-of-q_private_slot/3, with Qt > 5 and C++11 it is a useless macro.
the moc file generated:
#include "../../MyButton.h"
#include <QtCore/qbytearray.h>
#include <QtCore/qmetatype.h>
...
case 0: _t->d_func()->onClicked((*reinterpret_cast< bool(*)>(_a[1]))); break;
...
notice: _t->d_func()->onClicked invoke the private class's func(but no include)
so absolutely result in compile error. the question is moc file doesnt include MyButton_p.h, and manually add the include:
#include "../../MyButton.h"
#include "../../MyButton_p.h"
...
then its ok(but the moc file shouldnt modify manually)

user-defined literals and whitespace and c++11 issues

I'm compiling very simple code and as output I receive error:
`../untitled6/main.cpp:17:1: error: unable to find string literal operator 'operator"" __FILE__'
connect(&d_t, SIGNAL(timeout()), this, SLOT(doPlay()));`
The code is following:
#include <QObject>
#include <QTimer>
class Test : public QObject
{
Q_OBJECT
public:
explicit Test(QObject *parent = 0) : QObject(parent) {}
void Play()
{
connect(&d_t, SIGNAL(timeout()), this, SLOT(doPlay()));
}
public slots:
void doPlay() {}
private:
QTimer d_t;
};
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
Test test;
test.Play();
return a.exec();
}
It is happened only if I include c++11 support in my project. Without this support the compilation is Okey. I have read about user-defined literals and whitespace for gcc ver. 4.7 when c++11 support is included. But my code doesn't include any FILE code.... I found that problem is related to SIGNAL and SLOT constructions. But I have no idea what is wrong here...
P.S. For compilation I use sh4-linux-g++ (GCC) 4.8.
I have found that this issue don't observed for release build configuration. It seems it is issue for debug build configuration...
This has been fixed in Qt 4.8.1:
https://bugreports.qt.io/browse/QTBUG-22847
You should upgrade.

Variadic signals and generic lambdas

Is it possible to create variadic signal and connect generic lambda as slot? I mean something like (say, all definitions of involved functions are visible where needed (e.g. at points of instantiation)):
#include <QCoreApplication>
#include <QObject>
#include <QTime>
class A
: public QObject
{
Q_OBJECT
public :
A(QObject * const parent = Q_NULLPTR)
: QObject{parent}
{ ; }
signals :
template< typename ...Ts >
void infoMessage(Ts... args);
public slots :
void run()
{
emit infoMessage("Started at ", QTime::currentTime());
}
};
#include <QTimer>
#include <QtDebug>
#include "main.moc"
int main(int argc, char * argv [])
{
QCoreApplication a{argc, argv};
A a;
auto printInfoMessage = [&] (auto... args)
{
(qInfo() << ... << args);
};
QObject::connect(&a, SIGNAL(infoMessage), printInfoMessage);
QTimer::singleShot(0, &a, &A::run);
return a.exec();
}
Currently it gives an error message:
AUTOGEN: error: process for main.cpp:18: Error: Template function as signal or slot
moc failed...
Here macro SLOT() instead of &A::infoMessage does not help a lot. Is there any workarounds to overcome this limitation?
I know, that some of the answers will contain a using of std::make_tuple and std::index_sequence stuff. But is there less verbose solution?
There is no direct workaround for having template. On of thea reason is that the moc indexes all signals and slots, and this cannot be done for function templates as function templates will generate several functions depending code that is generally not accessible from the moc.
I don't think you can make it work with tuple and such as these are also templates.
A solution could be to use QVariant and/or QVariantList for your arguments.
Please note that the error is not caused by the QObject::connect line, but the the signal declaration in class A.
Also, you cannot replace SIGNAL() and SLOT() at your will, it is either a signal or a slot, it cannot be both.
And finally you should be using this form:
QObject::connect(&a, &A::infoMessage, printInfoMessage);
And since printInfoMessage is using auto parameters, you might need to force the auto resolution using qOverload:
QObject::connect(&a, &A::infoMessage, qOverload<QVariantList>(printInfoMessage));

(epics)QT compilation error: "undefined reference to"

I am brand new to programming with Qt. I'm trying to do a simple subtraction of some values fed from an epicsQt widget called QELabel, which simply reads the value of an EPICS channel. I want to subtract values from two QELabels and print it to another QELabel. But, I'm getting 'undefined reference to' errors for these ->
MainWindow::on_qeLabel_dbValueChanged(QString const&) MainWindow::on_ShutterOpen_dbValueChanged(QString const&)
Here is the bit of mainwindow.cpp (I followed the example from this youtube video, especially after about the 15 minute mark)
void MainWindow::on_TopShutter_dbValueChanged(const QString &out)
{
double top,bottom,open;
top=ui->TopShutter->text().toDouble();
bottom=ui->BottomShutter->text().toDouble();
open=top-bottom
ui->ShutterOpen->setText(Qstring::number(open));
}
I'm using QTCreator, so I don't have the usual errors that I've been seeing in other forums. I have the slot declared in the header file, and MainWindow set as a Q_Object (this is the whole mainwindow.h file):
#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_qelabel_dbValueChanged(const QString &out);
void on_ShutterOpen_dbValueChanged(const QString &out);
void on_TopShutter_dbValueChanged(const QString &out);
private:
Ui::MainWindow *ui;
};
#endif //MAINWINDOW_H
Because they are short, and for completeness, here is the main.cpp, and then the .pro
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
And the FirstWeatherAlarm.pro:
#-------------------------------------------------
QT += core gui xml
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = FirstWeatherAlarm
TEMPLATE = app
SOURCES += main.cpp\
mainwindow.cpp
LIBS += -L/usr/lib64/qt5/plugins/designer -lQEPlugin
INCLUDEPATH += /home/jchavez/epicsqt/3.1.0/framework/include
HEADERS += mainwindow.h
FORMS += mainwindow.ui
Have I got everything declared right at the start of all the files? What is missing so that my slots are not right? I created the slot in the gui, using the "right-click" on my QELabel, and selecting "Go to Slot", so I should think all the formatting would be correct. As I've been editing, I've also run qmake and make clean which are other answers I've seen on forums. But nothing is working.
The problem is with two slots:
MainWindow::on_qeLabel_dbValueChanged(QString const&)
MainWindow::on_ShutterOpen_dbValueChanged(QString const&)
They are declared in MainWindow.h file and used somewhere in your project (otherwise you won't get an error).
But they are not implemented in mainwindow.cpp. You should add implementation to this file and the error will go away.
You have implementation for
void MainWindow::on_TopShutter_dbValueChanged(const QString &out)
in mainwindow.cpp, you can add implementation for two more slots. Think about slot as a function. And read more about signals/slots.

Resources