QT -- emit Signal / Slots

0

Powoli zbieram to jakoś do kupy, sorry za tyle wątków, ale czas mnie goni z projektem a przez nawał innych przedmiotów straciłem balans.

Więc tak, w klasie MainLoop, która dziedziczy QThread odpalam pętle, która znajdując elementy w kolejce "oczekujace" wyzwala sygnal co 2 sek za pomoca QTimer::SingleShot. Ten sygnał potrzebuje przechwycić w MainWindow i odpalić odpowiedni slot;

#include "mainloop.h"
#include "includes.h"
#include "mainwindow.h"
#include <QTimer>

MainLoop::MainLoop()
{
       run();
}

void MainLoop::run()
{
    while(1){
        if(MainWindow::oczekujace.empty()) continue;
        else{
            QTimer::singleShot(2000, this, SLOT(emit_move()));
        }
    }
}

void MainLoop::emit_move()
{
    emit move();
}
 

MainLoop definiuje wewnątrz konstruktora MainWindow:

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    MainLoop loop;
    count = 0; wolne = 0;
    connect(&loop, SIGNAL(move()), this, SLOT(MoveItemToAir()));
} 

Tylko otrzumuje błędy undefined reference to vtable for MainLoop i for MainLoop::move ;
Co robię źle?

1

Masz prosty przyklad uzycia wlasnych sygnalow i slotow z watkami.

https://github.com/Krycho/Qubic/tree/master/research/QThreadExample

0
No0b_ napisał(a):
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    MainLoop loop;
    count = 0; wolne = 0;
    connect(&loop, SIGNAL(move()), this, SLOT(MoveItemToAir()));
} 

Apropos co zrobiłeś źle - tworzysz sobie obiekt klasy MainLoop lokalnie na stosie podczas wykonywania się konstruktora MainWindow.W momencie jak nastąpi wyjście z niego obiekt loop zostanie zniszczony,więc nic nigdy do slotu MoveItemToAir nie trafi.

Kolejny błąd jaki widzę to odpalenie głównej pętli w konstruktorze obiektu MainLoop,na moje oko to właśnie jest powodem czemu dostajesz komunikaty o błędach vtable'a.

0

Mam to w końcu zrobione tak:

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    count = 0; wolne = 0;

    QThread* thread = new QThread;
    loop.moveToThread(thread);
    connect(thread,SIGNAL(started()),&loop,SLOT(start()));
    connect(thread, SIGNAL(finished()),&loop,SLOT(deleteLater()));
    connect(&loop, SIGNAL(move()), this, SLOT(MoveItemToAir()));
    thread->start();
} 
#include "mainloop.h"
#include "includes.h"
#include "mainwindow.h"
#include <QTimer>

MainLoop::MainLoop() : QObject()
{
}

void MainLoop::start()
{
    while(1){
        if(MainWindow::oczekujace.empty()) continue;
        else{
            QThread::msleep(2000);
            emit move();
        }
    }
}

MainLoop zdeklarowałem w nagłówku klasy, w sekcji public;

Źle też robiłem tworząc MainLoop dziedziczący QThread, robi się to tak, że naszą klasę tworzymy jako podstawowy obiekt QObject, a następnie przesyłamy go do obiektu QThread funkcją .moveToThread. Następnie podpinamy wszystko connectem i finalnie odpalamy start();

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.