I'm totaly new in QT programming so i got a bit noob question.
Why I get this error?
undefined reference to `Messenger::newParticipant(QString)'
main.cpp
#include <QCoreApplication>
#include <QTextStream>
#include "messenger.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
Messenger* messenger = new Messenger();
messenger->newParticipant("AAAA");
QTextStream qout(stdout);
qout << "asd\n";
qout.flush();
return a.exec();
}
messenger.h
#ifndef MESSENGER_H
#define MESSENGER_H
#include "network/client.h"
#include <iostream>
#include <QTextStream>
class Messenger
{
public:
Messenger();
void newParticipant(const QString &nick);
private slots:
void sendMessage(const QString &message);
void participantLeft(const QString &nick);
};
#endif // MESSENGER_H
messenger.cpp
#include "messenger.h"
Messenger::Messenger()
{
QTextStream qout(stdout);
qout << "a. Constructor...\n";
qout.flush();
}
void newParticipant(const QString &nick)
{
if (nick.isEmpty())
return;
QTextStream qout(stdout);
qout << nick;
qout.flush();
}
You forgot to specify classname in definition of newParticipant.
Try to change it to void Messenger::newParticipant(const QString &nick) in messenger.cpp.
That's because you forgot to write Messenger:: before newParticipant definition in your cpp file.
Related
I'm trying to use GLEW with QT in a QOpenGLWidget in Visual Studio.
Some details:
Visual Studio 2013
Glew 2.0.0 x64
QT 5.6.2 x64
I keep getting "Missing GL version" error when calling glewInit(). I've searched online a lot, and this problem seems to sometimes be caused by how the format is set (QSurfaceFormat), or how the functions create()/ makeCurrent() / doneCurrent() are used. But I can't seem to find a working solution. I'm still a bit confused about the whole QOpenGLContext thing also.
I manage to get the QOpenGLWidget work without GLEW, and using "old" gl functions (glBegin(), glEnd(), etc...). And I also get GLEW to work with GLFW3.
Is there something I seem to misunderstand in the code below?
My subclass of QOpenGLWidget
MyGLWidget.h
#pragma once
#include <QWidget>
#include "GL\glew.h"
#include <QOpenGLWidget>
#include <gl/GLU.h>
#include <gl/GL.h>
#include <iostream>
#include "qopenglcontext.h"
#include "loadShader.h"
class MyGLWidget : public QOpenGLWidget
{
public:
MyGLWidget(QWidget *parent = 0);
~MyGLWidget();
public:
void initializeGL() override;
void resizeGL(int w, int h) override;
void paintGL() override;
};
MyGLWidget.cpp
#include "MyGLWidget.h"
MyGLWidget::MyGLWidget(QWidget *parent)
: QOpenGLWidget(parent)
{
QSurfaceFormat glformat;
glformat.setVersion(3, 2);
glformat.setOption(QSurfaceFormat::DeprecatedFunctions);
glformat.setSwapBehavior(QSurfaceFormat::DoubleBuffer);
glformat.setProfile(QSurfaceFormat::CompatibilityProfile);
QSurfaceFormat::setDefaultFormat(glformat);
this->setFormat(glformat);
create();
makeCurrent();
}
MyGLWidget::~MyGLWidget(){}
void MyGLWidget::initializeGL()
{
glewExperimental = TRUE;
GLenum err = glewInit();
if (GLEW_OK != err){
std::cout << "[Error] GLEW failed to initialize. " << (const char*)glewGetErrorString(err);
}
doneCurrent();
GLuint TextShader_ID = LoadShaders("Shaders/TextVertShader.vert", "Shaders/TextFragShader.frag");
}
void MyGLWidget::paintGL()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
void MyGLWidget::resizeGL(int w, int h)
{
//...
}
main.cpp
#include "OGLQT_test2.h"
#include <QtWidgets/QApplication>
#include "GL\glew.h"
#include <QOpenGLFunctions>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
OGLQT_test2 w;
w.show();
return a.exec();
}
OGLQT_test2.h
#pragma once
#include "GL\glew.h"
#include <QtWidgets/QMainWindow>
#include "ui_OGLQT_test2.h"
#include "qopenglcontext.h"
class OGLQT_test2 : public QMainWindow
{
Q_OBJECT
public:
OGLQT_test2(QWidget *parent = Q_NULLPTR);
private:
Ui::OGLQT_test2Class ui;
};
OGLQT_test2.cpp
#include "OGLQT_test2.h"
#include "MyGLWidget.h"
OGLQT_test2::OGLQT_test2(QWidget *parent)
: QMainWindow(parent)
{
ui.setupUi(this);
MyGLWidget* glwidget = new MyGLWidget(this);
glwidget->setFixedHeight(400);
glwidget->setFixedWidth(500);
glwidget->move(50, 50);
glwidget->initializeGL();
glwidget->resizeGL(400,500);
glwidget->paintGL();
}
It seems that you cannot do this:
glformat.setVersion(x, y);
with GLEW. It works with QOpenGLFunctions, but apparently, it doesn't work with GLEW. You may not be able to do this, either:
glformat.setOption(QSurfaceFormat::DeprecatedFunctions);
glformat.setSwapBehavior(QSurfaceFormat::DoubleBuffer);
glformat.setProfile(QSurfaceFormat::CompatibilityProfile);
Try removing the format.
Also, I think you're doing a little bit of a mess here:
glwidget->initializeGL();
glwidget->resizeGL(400,500);
glwidget->paintGL();
There is a simple way to do this, just do:
glwidget->resize(400,500);
glwidget->show();
resizeGL is an event called by resize. That goes the same for initializeGL() and paintGL() being called by show.
Another one is:
GLenum err = glewInit();
if (GLEW_OK != err){
std::cout << "[Error] GLEW failed to initialize. " << (const char*)glewGetErrorString(err);
}
doneCurrent();
Now why would you call doneCurrent here?
I'm trying to get the position updates in QCoreApplication, Following is the code i'm trying but i'm getting error as
QObject::connect: Cannot connect (null)::positionUpdated(QGeoPositionInfo) to QObject::positionUpdated(QGeoPositionInfo)
Code:
#include <QCoreApplication>
#include <QDebug>
#include <QObject>
#include <QtCore>
class MyClass : public QObject
{
// Q_OBJECT
public:
MyClass(QObject *parent = 0)
: QObject(parent)
{
qDebug() << "In class";
QGeoPositionInfoSource *source = QGeoPositionInfoSource::createDefaultSource(this);
qDebug() << source;
connect(source, SIGNAL(positionUpdated(QGeoPositionInfo)),
this, SLOT(positionUpdated(QGeoPositionInfo)));
source->startUpdates();
}
private slots:
void positionUpdated(const QGeoPositionInfo &info)
{
qDebug() << "Position updated:" << info;
}
};
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
qDebug("Qt running !");
MyClass *objmyclass = new MyClass;
return a.exec();
}
If i uncomment the Q_OBJECT i get error as:
:-1: error: the vtable symbol may be undefined because the class is missing its key function
i am trying to take a feedback data which is published from arduino and subscribed to my GUI created in QT.
Now i have main.cpp and mainwindow.cpp.
main.cpp
#include <QtGui>
#include <ros/ros.h>
#include <QApplication>
#include "../include/abc/main_window.hpp"
#include "std_msgs/String.h"
#include <std_msgs/UInt16.h>
#include <QMainWindow>
#include <std_msgs/Float32.h>
void chatterCallback(const std_msgs::UInt16 &fb_msg){
ROS_INFO("Feedback: [%f]", fb_msg.data);
ui.label_6->setText(QString("%1").arg(fb_msg.data));
}
int main(int argc, char **argv) {
ros::init(argc, argv, "talker");
ros::NodeHandle n;
ros::Subscriber sub = n.subscribe("feedback",1000, chatterCallback);
ros::spinOnce();
QApplication app(argc, argv);
abc::MainWindow w(argc,argv);
w.show();
w.setWindowTitle("GUI for Controlling Servo Motor");
app.connect(&app, SIGNAL(lastWindowClosed()), &app, SLOT(quit()));
int result = app.exec();
return result;}
mainwindow.cpp
namespace abc {
using namespace Qt;
QSerialPort *serial;
MainWindow::MainWindow(int argc, char** argv, QWidget *parent)
: QMainWindow(parent)
, qnode(argc,argv)
{
ui.setupUi(this);
}
MainWindow::~MainWindow() {}
void MainWindow::on_horizontalSlider_valueChanged(int value)
{
ui.label_5->setText(QString("%1").arg(value));
msg.data = ui.label_5->text().toUInt();
ROS_INFO("%d", msg.data);
chatter_pub.publish(msg);
ros::spinOnce();
}
main_window.hpp
#ifndef abc_MAIN_WINDOW_H
#define abc_MAIN_WINDOW_H
#include <QtGui/QMainWindow>
#include "ui_main_window.h"
#include "qnode.hpp"
#include <QtSerialPort/QSerialPort>
#include <ros/ros.h>
#include "std_msgs/UInt16.h"
namespace abc {
class MainWindow : public QMainWindow {
Q_OBJECT
public:
MainWindow(int argc, char** argv, QWidget *parent = 0);
~MainWindow();
public Q_SLOTS:
private:
Ui::MainWindowDesign ui;
ros::NodeHandle n;
ros::Publisher chatter_pub = n.advertise <std_msgs::UInt16> ("chatter", 1000);
QSerialPort *arduino;
QNode qnode;
};
} // namespace abc
#endif // abc_MAIN_WINDOW_H
Now when i run this code, it shows me that UI is not declared in main.cpp.
I wanted to display the data from feedback to label_6 (TextBox). The data is only available in main.cpp, any suggestions are highly appreciable.
Thanks in advance.
You will have to pass the fb_msg.data as an argument to the MainWindow constructor. Then you can set the UI element in the MainWindow thread.
Alternatively once you create the MainWindow instance in your main, you can emit a signal which you catch and process in the MainWindow thread.
You cannot modify the UI elements from a different thread.
I observed that through task mgr, the memory increases in steps of 4kB and 8kB, though not necessarily in this order.
Possible duplicate: Windows Task Manager shows process memory keeps growing even though there are no memory leaks
I am not sure whether this's occurring because I did not release the QTimer object, timer2. Please advise me how to stop this memory increase, and whether my guess of why it's occurring, is correct.
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QtCore>
#include <QDebug>
#include <QDateTime>
#include <QFileInfo>
#include <QString>
#include <opencv/cv.h>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#define TIMER2_VALUE 3000
#define UPDATED_IMAGE_STORAGE_PATH "E:\\QT1\\timeStampDateMod2\\TimeStampDateMod2\\updatedRefImg.JPG"
#define UPDATED_IMAGE_BACKUP_PATH "E:\\QT1\\timeStampDateMod2\\TimeStampDateMod2\\backUp\\updatedRefImg[%1].JPG"
using namespace std;
using namespace cv;
typedef struct
{
QDateTime dateTimeMod1;
QDateTime dateTimeMod2;
}tTimeMods;
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
QTimer *timer2;
tTimeMods findTimeModifiedStruct();
QDateTime findTimeModified();
void compareTimeMods(tTimeMods timeTypeFunction, QDateTime dateTimeMod2);
QString appendWithImageName(tTimeMods timeTypeFunction);
void shiftToRepository(QString pathString);
void updatedImgToRepository(QString pathString);
public slots:
void timerSlot2();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
tTimeMods timeTypeFunction, timeTypeMain;
QDateTime dateTimeMod2;
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
timeTypeMain = findTimeModifiedStruct();
timer2 = new QTimer(this);
connect(timer2, SIGNAL(timeout()), this, SLOT(timerSlot2()));
timer2->start(TIMER2_VALUE);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::timerSlot2()
{
dateTimeMod2 = findTimeModified();
compareTimeMods(timeTypeMain, dateTimeMod2);
//delete timer2;
}
//tTimeMods findTimeModifiedStruct()
tTimeMods MainWindow::findTimeModifiedStruct()
{
QString myFileName = UPDATED_IMAGE_STORAGE_PATH;
QFileInfo info(myFileName);
/*find last date modified*/
timeTypeFunction.dateTimeMod1 = info.lastModified();
timeTypeFunction.dateTimeMod2 = info.lastModified();
qDebug()<< "dateTimeMod1: " << timeTypeFunction.dateTimeMod1.toString() << endl << "dateTimeMod2: "<< timeTypeFunction.dateTimeMod2.toString();
return(timeTypeFunction);
}
QDateTime MainWindow::findTimeModified()
{
QString myFileName = UPDATED_IMAGE_STORAGE_PATH;
QFileInfo info(myFileName);
QDateTime dateTimeMod2 = info.lastModified();
qDebug()<< "dateTimeMod2: "<< dateTimeMod2.toString();
return(dateTimeMod2);
}
void MainWindow::compareTimeMods(tTimeMods timeTypeFunction, QDateTime dateTimeMod2)
{
if(dateTimeMod2 >= timeTypeFunction.dateTimeMod1)
{
timeTypeFunction.dateTimeMod1 = dateTimeMod2;
QString pathString = appendWithImageName(timeTypeFunction);
shiftToRepository(pathString);
}
}
QString MainWindow::appendWithImageName(tTimeMods timeTypeFunction)
{
/*appending just the timeMod with the path & image name*/
QString path = QString(UPDATED_IMAGE_BACKUP_PATH).arg(timeTypeFunction.dateTimeMod1.toString());
qDebug()<< "path: " << path;
return path;
}
void MainWindow::shiftToRepository(QString pathString)
{
updatedImgToRepository(pathString);
}
void MainWindow::updatedImgToRepository(QString pathString)
{
pathString.replace(":","-");
pathString.replace(1,1,":");
qDebug()<<"pathString now: "<<pathString;
/*convert QString into char* */
QByteArray pathByteArray = pathString.toLocal8Bit();
const char *path = pathByteArray.data();
IplImage *InputImg = cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,3);
InputImg = cvLoadImage(UPDATED_IMAGE_STORAGE_PATH ,CV_LOAD_IMAGE_UNCHANGED);
/*save the image*/
cvSaveImage(path,InputImg);
cvReleaseImage(&InputImg);
}
I'm not familiar with OpenCV, but it seems that these two lines cause you memory leak:
IplImage *InputImg = cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,3);
InputImg = cvLoadImage(UPDATED_IMAGE_STORAGE_PATH ,CV_LOAD_IMAGE_UNCHANGED);
In the first line you are creating an object, but in the second you are assigning another object to the pointer without releasing the previous one, so the previous one gets leaked.
Is creating an image even needed, while you are going to load it?
.h
#include <QObject>
#include <QDebug>
class MyClass : public QObject
{
Q_OBJECT
public:
Q_INVOKABLE void cppMethod (const QString &msg)
{
qDebug() << "Called the C++ method with" << msg;
}
public slots:
void cppSlot (int number)
{
qDebug() << "Called the C++ slot with" << number;
}
};
.cpp
#include <QtCore/QCoreApplication>
#include <QDeclarativeEngine>
#include <QDeclarativeComponent>
#include <QDeclarativeContext>
#include <QDeclarativeView>
#include <QVariant>
#include <QMetaObject>
#include "cppFromQml.h"
int main (int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QDeclarativeView view;
return a.exec();
}
This results in segmentation fault. What's the way out?
Qt: 4.8.1
note that you're not using MyClass, and - just my guess - a declarative view will need a QApplication to properly run.
To better understand, I created a project, dumped almost all away (just kept the .pro, where I added qt += declarative), and changed a bit your code as follow:
#include <QApplication>
#include <QDeclarativeEngine>
#include <QDeclarativeComponent>
#include <QDeclarativeContext>
#include <QDeclarativeView>
#include <QVariant>
#include <QMetaObject>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QDeclarativeView view;
view.show();
return a.exec();
}
now it runs and display an empty view, as expected...