• 7823阅读
  • 15回复

进度条的问题,半天都没解决 [复制链接]

上一主题 下一主题
离线bingogo
 
只看楼主 倒序阅读 楼主  发表于: 2009-07-13


我用QProgressDialog编写一个进度条,但是遇到了问题,
大家来看看。

---------------
QProgressDialog progressDlg("Progress", "Cancel", 0, 100, this);

progressDlg.show(); //Calling this here only shows the title bar, no button and label. Why?
// progressDlg.exec(); Can not call this here, because the next step will never be executed.
// Unless there's a non blocking call to exec.

myFunction() ; // Do something here and show the result text to a dialogue

progressDlg->setValue(progressDlg->maximum());
progressDlg->close();
---------------


myFunction() ; -- 这里,我用了一个多线程来执行一些任务

问题在于用exec() 可以显示进度条,但是会阻塞而不执行下面的任务,
那我用进度条就没有意义了。
而如果用show()的话,进度条只显示标题栏,进度条和CANCEL按钮都不显示
有遇到过这种情况的吗?

谢谢!
离线shiroki

只看该作者 1楼 发表于: 2009-07-13
你的myfunciton里如果是阻塞性的操作就会影响dialog和其他界面的刷新了。 这个应该是你show的时候其他东西都没刷出来的原因
--
shiro is White
ki is tree
http://www.cuteqt.com
论坛 http://www.cuteqt.com/bbs
博客 http://www.cuteqt.com/blog
博客镜像: http://sites.cuteqt.com/cuteqt
Linux/Qt/嵌入式讨论群 http://qun.qq.com/air/5699823
离线bingogo
只看该作者 2楼 发表于: 2009-07-13
> 你的myfunciton里如果是阻塞性的操作就会影响dialog和其他界面的刷新了。
>这个应该是你show的时候其他东西都没刷出来的原因

你说的是对了,
一般怎么解决这种问题呢?
离线shiroki

只看该作者 3楼 发表于: 2009-07-13
阻塞性的操作要开线程来处理
qt里有个分型的例子, cuteqt上有个多线程的blog
http://www.cuteqt.com/blog/?p=547
--
shiro is White
ki is tree
http://www.cuteqt.com
论坛 http://www.cuteqt.com/bbs
博客 http://www.cuteqt.com/blog
博客镜像: http://sites.cuteqt.com/cuteqt
Linux/Qt/嵌入式讨论群 http://qun.qq.com/air/5699823
离线bingogo
只看该作者 4楼 发表于: 2009-07-13
> 阻塞性的操作要开线程来处理
> qt里有个分型的例子, cuteqt上有个多线程的blog
> http://www.cuteqt.com/blog/?p=547

呵呵~你的例子我今天早上看过,GOOGLE到的 ^o^
不过没太仔细,我再看一遍!
离线bingogo
只看该作者 5楼 发表于: 2009-07-13
仔细看几遍了你的例子,
你是在GUI线程中创建新的线程来执行图片缩放的操作
然后用信号的方式把信息传给GUI线程.

而我也有类似的操作,
在GUI线程中,创建多个线程来执行不同任务,
最后分别用wait()来等待线程的结束。
这个阻塞操作应该就是show()之后进度条没有完全显示的原因。
不知道我分析得对不对?

如果我要解决这个问题,
是不是也要在新建的线程中使用信号机制向GUI线程传递消息?

本人愚钝,还请多指教!
谢谢!
离线20044454
只看该作者 6楼 发表于: 2009-07-13
你可以声明GUI界面对象为全局的 一个指针 让QThread 的parent= 这个指针 在你QThread 的run() 里面直接对指针->QProgress->setValue()就可以了 ,
按说应该是QThread线程不可以直接和GUI交互的
让我做一个Qt的大牛!!!!
离线bingogo
只看该作者 7楼 发表于: 2009-07-14
还是把代码贴上吧……

----------------------
void MainWindow::SysInfoFunc()
{
    SysInfoDlg *p_ShowSysInfoDlg = new SysInfoDlg( );
    p_ShowSysInfoDlg->exec();
}

SysInfoDlg::SysInfoDlg(QWidget *parent)
    : QDialog( parent )
{
  textLabel = new QLabel();

  thread1.start();  // A task
  thread2.start();  // Another task

  thread1.wait(); // wait for task finished, and set text to the label
  thread2.wait(); // like thread1 ...

  textLabel->setText( ... );

}
------------------------------------

加入进度条后是这样的。

---------------------------------------------
void MainWindow::SysInfoFunc()
{

    progressDlg = new QProgressDialog("Operation in progress.", "Cancel", 0, 100, this);
    connect(progressDlg, SIGNAL(canceled()), this, SLOT(cancelProgressDlg()));
    timer = new QTimer(this);
    connect(timer, SIGNAL(timeout()), this, SLOT(performProgressDlg()));
    timer->start(0);

    progressDlg->setValue(0);
  
    SysInfoDlg *p_ShowSysInfoDlg = new SysInfoDlg(node);
    p_ShowSysInfoDlg->exec();

    progressDlg->setValue(progressDlg->maximum());

}

void MainWindow::cancelProgressDlg()
{
    timer->stop();
    progressDlg->close();
}

void MainWindow::performProgressDlg()
{
    if(progressDlg->value() + 1 < progressDlg->maximum())
    {
        progressDlg->setValue(progressDlg->value() + 1);
    }
    else
    {
        timer->stop();
        progressDlg->close();
    }

    qApp->processEvents();  
}
--------------------------------

进度条只有在SysInfoDialog弹出之后,才弹出来。
这样,我的进度条就没有加上的必要了。

Thanks.
离线bingogo
只看该作者 8楼 发表于: 2009-07-14
引用第6楼20044454于2009-07-13 20:21发表的  :
你可以声明GUI界面对象为全局的 一个指针 让QThread 的parent= 这个指针 在你QThread 的run() 里面直接对指针->QProgress->setValue()就可以了 ,
按说应该是QThread线程不可以直接和GUI交互的


楼上的办法我没有理解清楚,可以说得详细一点吗?
离线20044454
只看该作者 9楼 发表于: 2009-07-14
这个是我做的进度条不是QProgress  是QSlider http://www.qtcn.org/bbs/read.php?tid=19944&keyword=%D7%EE%B4%F3%BB%AF
你不知道和你想的怎么样?
让我做一个Qt的大牛!!!!
离线shiroki

只看该作者 10楼 发表于: 2009-07-14
不要去wait子线程阿,去响应一下子线程的finished信号就行啦, 就像我那个例子里写的那样。 wait是会阻塞的, 不应该放在gui线程里
--
shiro is White
ki is tree
http://www.cuteqt.com
论坛 http://www.cuteqt.com/bbs
博客 http://www.cuteqt.com/blog
博客镜像: http://sites.cuteqt.com/cuteqt
Linux/Qt/嵌入式讨论群 http://qun.qq.com/air/5699823
离线bingogo
只看该作者 11楼 发表于: 2009-07-15
引用第10楼shiroki于2009-07-14 17:19发表的  :
不要去wait子线程阿,去响应一下子线程的finished信号就行啦, 就像我那个例子里写的那样。 wait是会阻塞的, 不应该放在gui线程里


> 不要去wait子线程阿
可是我需要等待子线程全部完成,才可以进行下一步操作……

> 去响应一下子线程的finished信号就行啦
也就是说要用一个处理函数来接受每个子线程的finished信号?
怎么判断所有子线程都结束了?
离线bingogo
只看该作者 12楼 发表于: 2009-07-15
class Thread_showSysInfo : public QThread
{
    Q_OBJECT
public:
    void run();
signals:
    void Finished();
};


SysInfoDlg::SysInfoDlg()
{

    connect(showSysInfoThread, SIGNAL(Finished()), this, SLOT(FinishedProcessFunc()));
    showSysInfoThread.start();

}


编译的时候出现下列错误……
SysInfoDlg.cpp:386: error: no matching function for call to 'SysInfoDlg::connect(Thread_showSysInfo&, const char [12], SysInfoDlg* const, const char [23])'
/usr/include/QtCore/qobject.h:202: note: candidates are: static bool QObject::connect(const QObject*, const char*, const QObject*, const char*, Qt::ConnectionType)
/usr/include/QtCore/qobject.h:307: note: bool QObject::connect(const QObject*, const char*, const char*, Qt::ConnectionType) const

明明跟你的例子一样的,晕~
恩,我再看看错在哪了……
离线浪迹江湖

只看该作者 13楼 发表于: 2009-07-15
我遇见过和楼主一样的问题,这种问题开多线程就可以和解决
离线bingogo
只看该作者 14楼 发表于: 2009-08-03
前段时间没去搞这个问题

现在解决了,

*多线程 + 信号机制*
搞定!
离线bingogo
只看该作者 15楼 发表于: 2009-08-03
谢谢楼上各位的帮助!!  
快速回复
限100 字节
 
上一个 下一个