【问题标题】:QThread::msleep() freezes programQThread::msleep() 冻结程序
【发布时间】:2013-10-22 05:02:15
【问题描述】:

当用户保存他们的游戏时,我正在尝试在我的QLabel 之一上创建淡入淡出效果。

所以,我认为使用QThread 会非常适合这项工作,但唯一的问题是QThread::msleep(); 会冻结程序。

我以前多次使用这种技术来减慢循环速度,但现在它决定冻结我的程序直到循环结束。

有人对这里发生的事情有任何想法吗?

我删除了所有不相关的东西,因为这个程序很大。

已保存.h

#ifndef SAVED_H
#define SAVED_H

#include <QThread>

class Saved : public QThread
{
    Q_OBJECT
public:
    explicit Saved(QObject *parent = 0);
    void run();
signals:
    void reduceVisibility(unsigned short);
public slots:

};

#endif // SAVED_H

保存的.cpp

#include "saved.h"

Saved::Saved(QObject *parent) :
    QThread(parent)
{

}

void Saved::run(){
    unsigned short alpha = 250;
    for(unsigned short i = 0; i <= 5; i++){
        emit reduceVisibility(alpha);
        alpha -= 50;
        QThread::msleep(250);
    }
}

主窗口.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

// QThread
#include "saved.h"

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

    Saved *saving;

private slots:

public slots:
    void animateSave(unsigned short);
private:
    Ui::MainWindow *ui;
};

main.cpp

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

#include <QApplication>
#include <QFile>
#include <QTextStream>

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

    // QThread
    saving = new Saved(this);
    connect(saving, SIGNAL(reduceVisibility(unsigned short)), this, SLOT(animateSave(unsigned short)));
}

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

// Buttons
void MainWindow::on_Btn_Save_clicked(){
    QFile saveFile("save.txt");
    saveFile.open(QIODevice::WriteOnly | QIODevice::Text);
    QTextStream out(&saveFile);
    out << user.getUsername() + "\n" + user.getLevel();
    saveFile.close();

    saving->run();
    saving->quit();
}

// Slots
void MainWindow::animateSave(unsigned short Visibility){
    QString visible = QString::number(Visibility);
    ui->Lbl_Saved->setStyleSheet("color:rgb(0,255,255, " + visible + ");");
}

【问题讨论】:

  • 您犯了严重的错误,并将运行可见性更改为公开。你应该使用 QThread::start 来运行一个线程。永远不要直接调用 run

标签: c++ multithreading qt qthread qtcore


【解决方案1】:

您也可以查找QPropertyAnimation 的文档并将其与QWidget::windowOpacity 挂钩。这可能是最适合您的问题的方法。

例如:

void MyWidget::buttonClicked() // SLOT when button is clicked
{
    QPropertyAnimation* anim = new QPropertyAnimation(ui->Lbl_Saved, "windowOpacity"); // new animation, hooked on the labels window opacity
    anim->setDuration(2500); // use 2.5 seconds for disapearing
    anim->setStartValue(1.0f); // from full visible
    anim->setEndValue(0.0f); // to invisible
    connect(anim, SIGNAL(finished()), anim, SLOT(deleteLater())); // delete object when animation done
    anim->start();
}

【讨论】:

    【解决方案2】:

    有人对这里发生的事情有任何想法吗?

    这是针对(see QThread: QObject)。接收者MainWindow 在另一个线程中。由于默认连接是AutoConnection,Qt 将使用QueuedConnection 并在与MainWindow 对象相同的线程中运行插槽animateSave

    但是,您根本不应该使用QThread。您不想同时做一些事情,而是希望在给定时间(或之后)发生一些事情QTimer 就是你想要的。

    MainWindow::MainWindow(QWidget *parent)
    {
        /* ... */
        myTimer = new QTimer(this);
        connect(myTimer, SIGNAL(timeout(), this, SLOT(decreaseAlphaOrStop()));
    }
    
    void MainWindow::on_Btn_Save_clicked(){
        /* .. snip .. */
        alpha = 250;
        myTimer->start(250);    
    }
    
    // new slot
    void MainWindow::decreaseAlphaOrStop(){
        alpha -= 50;
        if( alpha < 0){
            alpha = 0;
            myTimer->stop();
        }
        animateSave(alpha);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-10-31
      • 1970-01-01
      • 2018-11-08
      • 2017-05-22
      • 2020-12-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多