1
votes

I have some troubles in correct set of Signal and Slots between one class in which I do some calculations and the other one which contain GUI with my progress bar. I have very small experience with qt so I don't feel well how the signal/slots works. I tried few manuals and tutorials but I still don't know how to set it.

Let's call the progress bar class mainwindow

mainwindow.h

#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_pushButton_clicked();

private:
    Ui::MainWindow*ui;
};

#endif // LOADING_H

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "calc.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    ui->progressBar->setValue(0);
    calc sender;
    connect(&sender, SIGNAL( inprogress(int) ), ui->progressBar, SLOT( setValue(int) ) );
}


MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_pushButton_clicked()
{
    calc clc;
    clc.doData();
}

Signal is emitted from calculation class, call it short calc

calc.h

#ifndef CALC_H
#define CALC_H

#include <QObject>

class calc : public QObject
{
Q_OBJECT
public:
    calc(QObject *parent=0);
    void doData();
    void printResults(int t);
signals:
    void inprogress(int progr);

};

#endif // CALC_H

calc.cpp

#include "calc.h"
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>

int t = 0;
int t_end = 100;
int progr = 0;

void calc::printResults(int t)
{
    progr = t;
    emit inprogress(progr);
    QCoreApplication::processEvents(); //Prevent GUI freeze.
}

void calc::doData()
{
    for ( int i = 1; i <= t_end; i++ )
    {
        t++;
        printResults(t);
        qDebug()<<t;
    }
}

calc::calc(QObject *parent)
{

}

Archiev part (code above edited) The compilation ends with this error: no matching function for call to 'loading::connect(calc*, const char*, QProgressBar*&, const char*) Do I use signals in correct way, or I misunderstand this concept? What's the >correct way to update value of progress bar during this calculations?

EDIT: Code edited to be more clear, now it show current question - signal works but has no effect on qprogressbar.

EDIT2: Now works - function has to be call sender->doData(). Additionally correct assignment is sender = new calc(this) (with calc *sender added to private section of mainwidnow.h). Thanks you, everyone, for help, especially @eyllanesc for point correct way!

2
calc must be QObject-based. sod right way is class calc : public QObject { Q_Object public: calc(QObject *prnt) : QObject(prtn) {....} ..... And you create your calc but you didn't strore it. So when you go out of constructor scope your calc exemplar will be destroyedAndrey Semenov
At what time do you call the doData function?eyllanesc
it's called when user push buton placed under progress bar, look: void MainWindow::on_pushButton_clicked()Karls

2 Answers

0
votes

Only the classes that inherit from QObject can have signals, in addition they must have the Macro Q_OBJECT, since this through the MOC creates all the necessary metaclass for the connection between signals and slots. In your case:

*.h

class calc: public QObject
{
Q_OBJECT
    public:
        calc(QObject *parent=0);
        void signalProgress();
    signals:
        void inprogress();

};

*.cpp

[...]

calc::calc(QObject *parent): QObject(parent)
{

}

Also create a calc instance through a pointer as the garbage collector will delete that data after you use the constructor.

*.h

private:
    Ui::loading *ui;
    calc *sender;

*.cpp

loading::loading(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::loading)
{
    ui->setupUi(this);
    ui->progressBar->setValue(0);
    sender = new calc(this);
    connect(sender, SIGNAL( inprogress(int) ), ui->progressBar, SLOT( setValue(int) ) );
}
0
votes

You need to use QObject-based class in order to establish a connection

In your calc header file, you will have to inherit from QObject and then to add the Q_OBJECT macro

calc.h

class calc : pubilc QObject
{
   Q_OBJECT
public:
    calc();
    void signalProgress();
signals:
    void inprogress(int progr);

};

There's tons of examples and documentation using Qt signals & slots you can start reading here

P.S.

QProgressBar is also Object-based class so the same logic is already implemented here.