вторник, 19 июня 2012 г.

Заморозка GUI в Qt

Для решения проблем заморозки GUI и реализации отзывчивых приложений необходимо придерживаться советов из следующих статей:
http://doc.qt.nokia.com/qq/qq27-responsive-guis.html
http://qt-project.org/wiki/Progress-bar

Класс для выполнения длительных операций в отдельном потоке с выводом QProgressBar:

file.h



typedef boost::function< void () > BusyFunction;

class Busy : public QObject
{
    Q_OBJECT

public:

    Busy( const QString& label
          , const BusyFunction& longOperationFunction
          , QWidget* parentWidget );
 
private:
 
    void start();
 
private:

    CONST_PROPERTY( QPointer< QFutureWatcher< void > >
                    , watcher );
 
    CONST_PROPERTY( QPointer< QProgressDialog >, progress );

    CONST_PROPERTY( BusyFunction, longOperationFunction );
};


file.cpp


Busy::Busy( const QString& label
            , const BusyFunction& longOperationFunction
            , QWidget* parentWidget )
    : QObject()
      , INIT_PROPERTY( watcher, new QFutureWatcher< void >( this ) )
      , INIT_PROPERTY( progress
                       , new QProgressDialog( label, QString(), 0, 0
                                              , parentWidget ) )
      , INIT_PROPERTY( longOperationFunction, longOperationFunction )
{
    this->progress()->setWindowFlags( Qt::Tool | Qt::CustomizeWindowHint
                                          | Qt::WindowTitleHint );
 
    this->progress()->setWindowModality( Qt::WindowModal );

    this->progress()->setCancelButton( 0 );

    connect( this->watcher(), SIGNAL( finished() )
             , this->progress(), SLOT( cancel() ) );

    this->start();
}

void Busy::start()
{
    QFuture< void > future = QtConcurrent::run( this->longOperationFunction() );

    this->watcher()->setFuture( future );

    this->progress()->exec();
}


Комментариев нет:

Отправить комментарий