Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets > Проблема со вторым потоком, Секундомер обр. отсче


Автор: SpAwN3D 13.2.2012, 13:19
По сути должно отсчитывать секунды при нажатии на кнопку,но когда во втором doWork() потоке создаю бесконечный цикл со Sleep"ом внутри программа вылетает.Если ли другие варианты вместо Sleep или же по другому создать второй тред ?
Код

#include "countdown.h"
#include "ui_countdown.h"
#include <windows.h>
#include <iostream>
#include <process.h>
#include <QThread>
countDown::countDown(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::countDown)
{
    ui->setupUi(this);
    countMS = c = 1000;
    ui->label->setText(QString::number(countMS));
    work = false;
    connect(ui->bStart,SIGNAL(clicked()),this,SLOT(start()));
    connect(ui->bPause,SIGNAL(clicked()),this,SLOT(pause()));
}

void countDown::start()
{
    work = true;
}
void countDown::pause()
{
    work = false;
}
void countDown::stampa()
{
    ui->label->setText(QString::number(countMS));
}

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

void countDown::doSetup(QThread &cThread)
{
    connect(&cThread,SIGNAL(started()),this,SLOT(doWork()));
}

void countDown::doWork()
{
    while(1)
    {
        if(work)
        {
            Sleep(1000);
            countMS--;
        }
        ui->label->setText(QString::number(countMS));
    }
}



main

Код

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    countDown w;
    w.show();
    QThread cThread;
    w.doSetup(cThread);
    w.moveToThread(&cThread);
    cThread.start();

    return a.exec();
}

Автор: Sality123 13.2.2012, 13:52
Мне секундомеры больше нравятся через таймеры. Они кстати сами работают в отдельном потоке.


Автор: SpAwN3D 13.2.2012, 13:59
QTimer не вариант, т.к. проблема состоит в том что бы самому сделать скажем что-то на него похожее

Автор: borisbn 13.2.2012, 14:07
Цитата(SpAwN3D @  13.2.2012,  13:19 Найти цитируемый пост)
w.moveToThread(&cThread);

GUI-классы ни в коем случае не должны работать в отдельном потоке.
Сделай наследника от QThread, в его ф-ции run() крути цикл, в котором emit'ай пустой сигнал. Законнекть этот сигнал на слот формы doWork, внутри которого просто делай Sleep и высветку.

Автор: SpAwN3D 13.2.2012, 14:39
Добавил такой класс
Код

class Thread : public QThread
{
    Q_OBJECT

signals:
    void aSignal();

protected:
    void run() {
        emit aSignal();
    }
};


и в мейн добавил такое:
Код

    Thread thread;
    QObject::connect(&thread, SIGNAL(aSignal()), &w, SLOT(doWork()));
    thread.start();


Результат тот же что и раньше, при запуске программа вылетает.
Или я не так понял?

Автор: borisbn 13.2.2012, 14:43
w.moveToThread(&cThread); это убрал ?
вообще, покажи весь код (все cpp и h). его там не должно быть много...

Автор: SpAwN3D 13.2.2012, 14:57
Цитата(borisbn @  13.2.2012,  14:43 Найти цитируемый пост)
w.moveToThread(&cThread); это убрал ?
вообще, покажи весь код (все cpp и h). его там не должно быть много... 


да,убрал

countDown.h
Код

#ifndef COUNTDOWN_H
#define COUNTDOWN_H

#include <QMainWindow>
#include <QThread>
namespace Ui {
class countDown;
}

class countDown : public QMainWindow
{
    Q_OBJECT

public:
    int countMS; // contatore per LED
    int c; // var per ins.
    bool work;
    explicit countDown(QWidget *parent = 0);
    ~countDown();
    //void count(void *p);
    void doSetup(QThread &cThread);
public slots:
    void start();
    void doWork();
    void pause();
    void stampa();

    
private:
    Ui::countDown *ui;
};

class Thread : public QThread
{
    Q_OBJECT

signals:
    void aSignal();

protected:
    void run() {
        emit aSignal();
    }
};

#endif // COUNTDOWN_H


countDown.cpp
Код

#include "countdown.h"
#include "ui_countdown.h"
#include <windows.h>
#include <iostream>
#include <process.h>
#include <QThread>
countDown::countDown(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::countDown)
{
    ui->setupUi(this);
    countMS = c = 1000;
    ui->label->setText(QString::number(countMS));
    work = false;
    connect(ui->bStart,SIGNAL(clicked()),this,SLOT(start()));
    connect(ui->bPause,SIGNAL(clicked()),this,SLOT(pause()));
}

void countDown::start()
{
    work = true;
}
void countDown::pause()
{
    work = false;
}
void countDown::stampa()
{
    ui->label->setText(QString::number(countMS));
}

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

void countDown::doSetup(QThread &cThread)
{
    connect(&cThread,SIGNAL(started()),this,SLOT(doWork()));
}

void countDown::doWork()
{
    do
    {
        if(work)
        {
            Sleep(1000);
            countMS--;
        }
        ui->label->setText(QString::number(countMS));
    }while(countMS != 0);

}


main.cpp
Код

#include <QtGui/QApplication>
#include "countdown.h"
#include <QThread>
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    countDown w;
    w.show();
    Thread thread;
    QObject::connect(&thread, SIGNAL(aSignal()), &w, SLOT(doWork()));
    thread.start();
    return a.exec();
}


вообще-то ничего такого

Автор: borisbn 13.2.2012, 15:13
Код


class Thread : public QThread
{
    Q_OBJECT

public:
    Thread() : m_abort( false ) {}
    bool m_abort;
signals:
    void aSignal();

protected:
    void run() {
        do
        {
            msleep(1000);
            emit aSignal();
        }
        while ( !m_abort );
    }
};

...

void countDown::doWork()
{
    if ( work )
    {
        countMS--;
    }
    ui.label->setText(QString::number(countMS));
}

...

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    countDown w;
    w.show();
    Thread thread;
    QObject::connect(&thread, SIGNAL(aSignal()), &w, SLOT(doWork()));
    thread.start();

    int res = a.exec();
    thread.m_abort = true;
    return res;
}


такой код у меня работает, не вылетает, не виснет.

Автор: SpAwN3D 13.2.2012, 15:33
Цитата(borisbn @  13.2.2012,  15:13 Найти цитируемый пост)
такой код у меня работает, не вылетает, не виснет. 

Спасибо! Работает, но вот появилась другая проблема, появилась задержка, но думаю это решается.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)