每个tick都创建Qt新线程?

时间:2014-07-02 22:57:48

标签: c++ qt c++11

为什么QTimer的每个刻度都会创建新线程?我的应用程序需要尽可能长时间运行,但是在xx的滴答之后它会冻结,它仍在运行(它的响应),但是下一个滴答不会被执行。我查看调试信息,然后看到:

  

QThread :: start:创建thread()失败QThread :: start:失败   创建thread()QThread :: start:创建thread()失败   QThread :: start:创建thread()失败QThread :: start:失败   创建thread()QThread :: start:创建thread()失败   QThread :: start:创建thread()失败QThread :: start:失败   创建thread()

waat?

Tick每隔xx秒执行一次,信号位于QWidged(这是TabWidget的一个选项卡)

namespace Ui {
class accountTab;
}

class accountTab : public QMainWindow
{
    Q_OBJECT

public:
    explicit accountTab(QWidget *parent = 0);
    class player *_player;
    ~accountTab();

private slots:
    void on_clean_timer_clicked();

public:
    Ui::accountTab *ui;
};



void accountTab::on_clean_timer_clicked()
{
    if(user->timers.value("clean")->isActive()) {
        _player->timers.value("clean")->stop();
    }
    else if(!user->timers.value("clean")->isActive()) {
        _player->timers.value("clean")->start(1800000); //900000
    }
}

_player是一个简单的类。 _player-> clean()执行一些静态类,即try / catched。

player.h

class player : public QObject
{
    Q_OBJECT

public:
    player();
    ~player();
    player(Ui::accountTab *tab, std::string login, std::string password);
    player(Ui::accountTab *tab, User user);

public:
    bool logIn();
    Ui::accountTab *tab = new Ui::accountTab();

public slots:
    void clean();

private:
    User user;
    QMap<std::string, QTimer*> timers;
    void initializeTimers();
};

player.cpp

player::player(Ui::accountTab *tab, std::string login, std::string password)
{
    this->tab = tab;
    this->user.login = login;
    this->user.password = password;
}

player::~player()
{
    delete this->manager;
    delete this->tab;
}

bool player::logIn()
{
    ...
    Log::writeLog("Login completed!", *this);
    return true;
}

bool player::setup(bool saved, bool save)
{
    if(!this->logIn())
        return false;
    Packets::sendPacket("getSimulation", *this);
    this->initializeTimers();
    return true;
}

void player::initializeTimers()
{
    this->timers.insert("clean", new QTimer(this));
    connect(this->timers.value("clean"), SIGNAL(timeout()), this, SLOT(cleanZoo()));
}

void player::clean()
{
    Packets::sendPacket()
}

播放器类中的用户类保留登录名和密码。 定时器是QMap:QMap定时器; Packets :: sendPacket()是静态void

和sendPacket()

QString httpManager::sendPacket()
{
    QNetworkRequest request("https://www.google.pl/");

    if(headers.size() > 0) {
        for (QMap<const char*, const char*>::iterator i = headers.begin(); i != headers.end(); ++i)
            request.setRawHeader(i.key(), i.value());
    }

    QNetworkAccessManager *manager = new QNetworkAccessManager();
    manager->setCookieJar(this->cookies);
    QNetworkReply *reply = manager->get(request);

    QEventLoop loop;
    QObject::connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
    loop.exec();

    QList<QNetworkCookie> cookies = reply->manager()->cookieJar()->cookiesForUrl(QUrl(reply->url()));
    foreach(QNetworkCookie cookie, cookies)
    {
        this->cookies->insertCookie(cookie);
    }

    return reply->readAll().data();
}

执行QEventLoop以获得相同void的响应。这会创建新线程吗?

1 个答案:

答案 0 :(得分:1)

这里有一些问题:

  1. 您的应用程序应该只有一个QNetworkAccessManager所有代码都使用,不为每个调用创建一个,在main中创建一个并将其传递到需要的位置。

  2. 您需要按照手册中的说明使用deleteLater删除QNetworkReply

  3. 在函数中创建另一个事件循环通常不是一个好主意。在与httpManager信号相关联的班级QNetworkAccessManager::finished(QNetworkReply * reply)上创建一个插槽,阅读回复并从此处致电deleteLater