Emitting a signal not working properly - c++

I have a class called dosecalibration which contains dosecalibration.cpp and dosecalibration.h. The class is associated to a separate ui form. On the form, when a button is clicked, a signal is emitted.
There is a connection within main window to receive this signal, however it doesn't seem to be working. The code is as following:
dosecalibration.h :
#ifndef DOSECALIBRATION_H
#define DOSECALIBRATION_H
#include <QDialog>
#include <QDebug>
namespace Ui {
class dosecalibration;
}
class dosecalibration : public QDialog
{
Q_OBJECT
public:
explicit dosecalibration(QWidget *parent = 0);
~dosecalibration();
double dosefactor;
//bool dose;
private slots:
void on_useCharge_clicked();
void on_useCounts_clicked();
void on_pushButton_clicked();
// void on_pCSB_valueChanged();
// void on_countsSB_valueChanged();
signals:
void applydose();
private:
Ui::dosecalibration *ui;
};
#endif // DOSECALIBRATION_H
dosecalibration.cpp :
#include "dosecalibration.h"
#include "ui_dosecalibration.h"
dosecalibration::dosecalibration(QWidget *parent) :
QDialog(parent),
ui(new Ui::dosecalibration)
{
ui->setupUi(this);
ui->countsSB->setEnabled(false);
ui->countsSB->setValue(ui->pCSB->value()*100/9.6);
}
dosecalibration::~dosecalibration()
{
delete ui;
}
void dosecalibration::on_useCharge_clicked()
{
ui->countsSB->setEnabled(false);
ui->pCSB->setEnabled(true);
}
void dosecalibration::on_useCounts_clicked()
{
ui->pCSB->setEnabled(false);
ui->countsSB->setEnabled(true);
}
void dosecalibration::on_pushButton_clicked()
{
if(ui->useCharge->isChecked()){
dosefactor = ui->pCSB->value();
}
else if(ui->useCounts->isChecked()){
dosefactor = ui->countsSB->value();
}
emit applydose();
}
//void dosecalibration::on_pCSB_valueChanged()
//{
// ui->countsSB->setValue(ui->pCSB->value()*100/9.6);
//}
//void dosecalibration::on_countsSB_valueChanged()
//{
// ui->pCSB->setValue(ui->countsSB->value()*9.6/100);
//}
And mainwindow.h (only included the 'includes' and the slots):
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <AFE_variables.h>
#include <QMainWindow>
#include "FPGA/fpga.h"
#include "FPGA/okFrontPanelDLL.h"
#include "decoder.h"
#include "analysis.h"
#include "about.h"
#include "logfile.h"
#include "Graph/graphicsscene.h"
#include "Graph/graphdialog.h"
#include "Graph/qcustomplot.h"
#include "Graph/graphicsview.h"
#include "settingsdialog.h"
#include "dosecalibration.h"
#include <QFileDialog>
#include <QProgressBar>
#include <QGraphicsScene>
#include <QGraphicsRectItem>
#include <QGraphicsTextItem>
#include <QDialog>
#include <QDebug>
#include <math.h>
slots:
//Dose calibration
void InitialiseGraphsAfterDose();
void on_actionDose_Calibration_4_triggered();
//void doseCalibrationEnabled();
private:
//Initalisation
void onStart();
void AllocateMemory();
void ConnectFPGA();
bool CheckConnection();
Ui::MainWindow *ui;
okCFrontPanel *xem;
FPGA *fpga;
QProgressBar *progressBar;
QTimer *PlayTimer;
LogFile *logfiledialog;
LogFile *logfileanalysis;
QString LoadLogFilePath;
dosecalibration *dose;
and a snippet from graphing.cpp, which is a part of the main window class:
//connects for dose calibration
dose = new dosecalibration(this);
connect(dose,SIGNAL(applydose()),this,SLOT(InitialiseGraphsAfterDose()));
}
void MainWindow::InitialiseGraphsAfterDose()
{
apply_dose = true;
InitialiseGraphs();
qDebug() << apply_dose;
}
So the applydose() signal is emitted at the push of a button in the dosecalibration ui. The connect should mean that the value of apply_dose is sent to console, however nothing is displayed.
EDIT:
Placing the connect within an if statement to determine if it is truly connecting confirms that it is indeed working correctly.
//connects for dose calibration
dose = new dosecalibration(this);
if(connect(dose,SIGNAL(applydose()),this,SLOT(InitialiseGraphsAfterDose())))
{
qDebug() << "connect worked";
}
}
The code above successfully outputs the message confirming the connect.
Any idea?

Remove the multiple instances of dosecalibration, or make sure to connect each one of those, if you really need multiple instances.

Related

Qt compiler error: 'emit' was not declared in this scope

I am trying to create a Simple GUI which creates multiple threads and perform some operation at the background while the GUI being responsive all the time. I am using QThreads of QT framework to achieve this but I am facing above said issue. Below is the code.
//Threading.h
This is my threading.h file.
#ifndef THREADING
#define THREADING
#include <QThread>
#include <QObject>
class Threading : public QThread
{
Q_OBJECT
private:
int num;
public:
explicit Threading(QObject * parent = 0);
void run();
void set_num(int);
int get_num();
Q_SIGNALS:
void someSignal(int);
};
//This is threading.cpp file
#include "threading.h"
#include <QtCore>
Threading::Threading(QObject *parent) : QThread(parent)
{
}
void Threading:: run()
{
emit someSignal(get_num());
}
void Threading :: set_num(int num)
{
QMutex mutex;
mutex.lock();
this->num = num;
mutex.unlock();
}
int Threading :: get_num()
{
return num;
}
//Mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QtCore>
#include "threading.h"
typedef unsigned char byte;
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
Threading *threadPointer;
};
//Mainwindow.cpp
In this file I am starting thread.
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "global.h"
#include <QtCore>
#include <QObject>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui-> setupUi(this);
threadPointer = new Threading(this);
connect(threadPointer,SIGNAL(someSignal(int)),this,SLOT(onSomeSignal()));
}
void MainWindow::on_clicked()
{
threadPointer->set_num(0);
threadPointer->start();
}
I saw some video online which has exactly similar code which is strangely but working fine and mine is not. Does it have to do with version ? Any help would be appreciated.
You can bypass the issue using Q_EMIT in place of emit, or just call the signal as a normal function (emit is optional and is there just for code readability):
void Threading:: run()
{
someSignal(get_num());
}
emit is an empty macro defined in qobjectdefs.h. You should investigate further, and try to understand why it is not defined (e.g. if QT_NO_KEYWORDS is defined somewhere and why).
You may also want to check if a
CONFIG += no_keywords
line exists in your pro file, as explained at the very end of this.

QT connect crash using signal accepted

I have a problem with my Qt code. I wanted to write an program which are taking a coordinates of point and then that point is drawing in point with that coordinates. My program doesn't have any errors or warnings when i built it but it's crashing at start(MainWindow doesn't show). This is my code:
main.cpp
#include < QApplication >
#include "mainwindow.h"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
MainWindow win;
win.show();
return app.exec();
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QWidget>
#include <QAction>
#include <QToolBar>
#include <QTextCodec>
#include <QObject>
#include <QDialog>
#include <QLineEdit>
#include <QPushButton>
#include <QString>
#include "addpoint.h"
class MainWindow: public QMainWindow
{
Q_OBJECT
private:
QToolBar *AddToolbar;
QAction *AddPointAction;
AddPoint *AddPointDialog;
QLineEdit *x;
public:
MainWindow();
void createToolbar();
void createActionAdd();
signals:
public slots:
void PointClicked();
void DialogAccepted();
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
MainWindow::MainWindow()
{
QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8"));
createActionAdd();
createToolbar();
connect(AddPointAction, SIGNAL(triggered(bool)), this, SLOT(PointClicked()));
connect(AddPointDialog, SIGNAL(accepted()), this, SLOT(DialogAccepted()));
setMinimumSize(480, 320);
}
/**/
void MainWindow::createToolbar()
{
AddToolbar = new QToolBar;
AddToolbar->addAction(AddPointAction);
addToolBar(AddToolbar);
}
/**/
void MainWindow::createActionAdd()
{
AddPointAction = new QAction("Add Road", this);
x = new QLineEdit(this);
x->setFixedSize(100, 30);
x->move(100, 100);
}
/**/
void MainWindow::PointClicked()
{
AddPointDialog = new AddPoint(this);
AddPointDialog->setModal(true);
AddPointDialog->exec();
}
/**/
void MainWindow::DialogAccepted()
{
x->setText("abc");
}
addpoint.h
#ifndef ADDPOINT_H
#define ADDPOINT_H
#include <QWidget>
#include <QTextCodec>
#include <QDialog>
#include <QObject>
#include <QLabel>
#include <QLineEdit>
#include <QPushButton>
#include <QString>
class AddPoint : public QDialog
{
Q_OBJECT
private:
QLabel *XpointL;
QLineEdit *XPoint;
QPushButton *OKButton;
public:
AddPoint(QWidget *parent);
void createButton();
signals:
public slots:
};
#endif // ADDPOINT_H
addpoint.cpp
#include "addpoint.h"
AddPoint::AddPoint(QWidget *parent) :QDialog(parent)
{
QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8"));
createButton();
connect(OKButton, SIGNAL(clicked(bool)), this, SLOT(accept()));
setMinimumSize(320, 240);
}
/**/
void AddPoint::createButton()
{
XpointL = new QLabel("Point X:", this);
XpointL->setFixedSize(100, 30);
XpointL->move(10, 10);
XPoint = new QLineEdit(this);
XPoint->setFixedSize(180, 30);
XPoint->move(120, 10);
OKButton = new QPushButton("OK", this);
OKButton->setFixedSize(100, 30);
OKButton->move(200, 150);
}
After running the program i see in aplication output lap:
"The program has unexpectedly finished."
"C:\QT\build-xxx-Desktop_Qt_5_4_2_MSVC2013_64bit-Debug\debug\xx.exe crashed"
I note that i made some experiments with this code and i saw that i have problem with signal accpeted() at mainwindow.cpp. I don't know what can i do with this problem. I hope you will help me.
AddPointDialog is uninitialized pointer, it does not yet point to valid AddPoint in MainWindow's constructor. You cannot call connect on that. Its value will change later, when you do AddPointDialog = new AddPoint(this); and only then will you be able to call connect.
Simply, you should move your connect call to void MainWindow::PointClicked() after you've initialized your pointer. I'd also make AddPointDialog local to that function and store it on the stack (you don't use it anywhere else and you're leaking memory).
The code would be:
void MainWindow::PointClicked()
{
AddPoint AddPointDialog(this);
AddPointDialog.setModal(true);
connect(&AddPointDialog, SIGNAL(accepted()), this, SLOT(DialogAccepted()));
AddPointDialog.exec();
}

Qt LNK1120 Unresolved External

I'm trying to make the following code work, but no idea why im getting this error.
Im having a mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "user.h"
#include <QObject>
#include <QEvent>
#include "logindialog.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void on_actionTest_triggered();
void on_actionExit_triggered();
private:
Ui::MainWindow *ui;
User *_User;
void doLogin(void);
User getUser(QString);
};
#endif // MAINWINDOW_H
and a windwindow.cpp
#include "mainwindow.h"
#include "ui_RMS_MainWindow.h"
#include "logindialog.h"
#include <QtCore>
#include <QtGui>
#include <QDebug>
#include <QApplication>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
this->installEventFilter(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void doLogin()
{
//LoginDialog aLoginDialog;
//aLoginDialog.setModal(true);
//aLoginDialog.exec();
qDebug() << "user log in needed";
}
void MainWindow::on_actionTest_triggered()
{
if(_User == NULL)
{
qDebug() << "user log in needed";
MainWindow::doLogin();
}
else
{
qDebug() << "sepp";
}
}
void MainWindow::on_actionExit_triggered()
{
QCoreApplication::quit();
}
When i try to run the code to open the dialog in the button triggered action it runs, when i try to call MainWindow::doLogin i get the "unresolved externals" error.
Hm. You have doLogin() function defined but it's not a MainWindow class method.
You need to define it as
void MainWindow::doLogin()
In windwindow.cpp you have:
void doLogin()
{
//LoginDialog aLoginDialog;
//aLoginDialog.setModal(true);
//aLoginDialog.exec();
qDebug() << "user log in needed";
}
You should change to:
void MainWindow::doLogin()
{
//LoginDialog aLoginDialog;
//aLoginDialog.setModal(true);
//aLoginDialog.exec();
qDebug() << "user log in needed";
}
As it is now this function is not implemented in MainWindow class.

Qt C++ - Custom slots

I'm trying to make some custom slots but it complains that the custom slots don't exist.
I have googled but can't find anything with a similar situation. No solutions worked for me.
QObject::connect: No such slot QSlider::setMinimum(int)
inkpuppet.cpp
#include "inkpuppet.h"
#include "ui_inkpuppet.h"
#include "aboutdialog.h"
#include <QDialog>
#include <QWidget>
#include <QtCore>
#include <QtGui>
#include <QButtonGroup>
#include <QSlider>
InkPuppet::InkPuppet(QWidget *parent) :
QWidget(parent),
ui(new Ui::InkPuppet)
{
ui->setupUi(this);
connect(ui->lowerFrameBox, SIGNAL(valueChanged(int)), ui->timeSlider, SLOT(setMinimum(int)));
connect(ui->upperFrameBox, SIGNAL(valueChanged(int)), ui->timeSlider, SLOT(setMaximum(int)));
//connect(ui->lowerFrameBox, SIGNAL(valueChanged(int)), ui->timeSlider, SLOT(setRange(int,int)));
}
InkPuppet::~InkPuppet()
{
delete ui;
}
void InkPuppet::on_aboutButton_clicked()
{
}
void InkPuppet::setMinimum(int value)
{
ui->timeSlider->setMinimum(value);
}
void InkPuppet::setMaximum(int value)
{
ui->timeSlider->setMaximum(value);
}
inkpuppet.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QtCore>
#include <QtGui>
#include "aboutdialog.h"
namespace Ui {
class InkPuppet;
}
class InkPuppet : public QWidget
{
Q_OBJECT
public:
explicit InkPuppet(QWidget *parent = 0);
~InkPuppet();
public slots:
void on_aboutButton_clicked();
void setMinimum(int value);
void setMaximum(int value);
private:
Ui::InkPuppet *ui;
AboutDialog *aDialog;
};
#endif // WIDGET_H
You try to connect your ui->lowerFrameBox valueChanged(int) signal with a setMinimum slot in ui->timeSlider. However, the setMinimum there is no slot. You need to connect to the slot in InkPuppet.
connect(ui->lowerFrameBox, SIGNAL(valueChanged(int)),
this, SLOT(setMinimum(int)));
In Qt 5.1 you can use connect in these ways too :
connect(ui->upperFrameBox,&QSlider::valueChanged,this,&InkPuppet::setMaximum);
connect(ui->upperFrameBox,&QSlider::valueChanged,&InkPuppet::setMaximum);
or even you can use c++11 lambda feauture.
connect(ui->upperFrameBox,&QSlider::textChanged,
[&](int value) {ui->timeSlider->setMaximum(value);});

Connect event/action to QPlainTextEdit

I have a QTabWidget which contains a QPlainTextEdit. I have managed to add action to the QTabWidget so that whenever a new tab opens, a new QPlainTextEdit is also added in the new tab. See code.
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QPlainTextEdit>
#include <QMessageBox>
#include <QAction>
#include <QTextCursor>
#include <iostream>
#include <QKeyEvent>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
setWindowTitle("Tilde");
current_tab = 1;
on_action_New_triggered();
ui->tabWidget->setTabsClosable(true);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_action_New_triggered()
{
QString newTab = "Tab " + QString::number(current_tab);
ui->tabWidget->addTab(new QPlainTextEdit, newTab);
ui->tabWidget->setCurrentIndex(current_tab - 1);
current_tab++;
editor = qobject_cast<QPlainTextEdit *>(ui->tabWidget->currentWidget());
editor->setFocus();
/*connect(editor->document(), SIGNAL(cursorPositionChanged(QTextCursor)),
this, SLOT(on_editor_cursorPositionChanged()));*/
}
void MainWindow::on_actionNew_document_triggered()
{
on_action_New_triggered();
}
void MainWindow::on_action_Exit_triggered()
{
QMessageBox msg;
msg.addButton(QMessageBox::Yes);
msg.addButton(QMessageBox::No);
msg.setText("Exit program?");
int selection = msg.exec();
if (selection == QMessageBox::Yes)
qApp->exit(0);
}
// highlight current line
void MainWindow::on_editor_cursorPositionChanged()
{
QTextEdit::ExtraSelection highlight;
highlight.cursor = editor->textCursor();
highlight.format.setProperty(QTextFormat::FullWidthSelection, true);
highlight.format.setBackground( QColor(240, 246, 217) );
QList<QTextEdit::ExtraSelection> extras;
extras << highlight;
editor->setExtraSelections(extras);
}
The commented code gives compiler error:
QMetaObject::connectSlotsByName: No matching signal for
on_editor_cursorPositionChanged()
I have added the function in the header file.
Header file:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QPlainTextEdit>
#include <QTextCursor>
namespace Ui
{
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void on_action_New_triggered();
void on_actionNew_document_triggered();
void on_action_Exit_triggered();
void on_editor_cursorPositionChanged();
private:
Ui::MainWindow *ui;
QPlainTextEdit *editor;
qint8 current_tab;
};
#endif // MAINWINDOW_H
Could it be that your signature for the SLOT is wrong?
/*connect(editor->document(), SIGNAL(cursorPositionChanged(QTextCursor)),
this, SLOT(on_editor_cursorPositionChanged()));*/
Should be?
connect(editor->document(), SIGNAL(cursorPositionChanged(QTextCursor)),
this, SLOT(on_editor_cursorPositionChanged(QTextCursor)));
Also, the naming convention you are using for that slot might be conflicting here with your manual connection. Qt may be trying to use the connectSlotsByName mechanism on your SLOT by matching the name: on_<member>_<signal>
In this case, the current signature of that SLOT on_editor_cursorPositionChanged() would match with the QPlainTextEdit editor member. And then you are manually connecting the document to it with the wrong signature. You probably should create another slot that is named more normally docCursorPosChanged(QTextCursor)