Qt 弹窗中布局的控件不显示问题

Ethan1994 2015-08-07 07:01:54
最近做一个小应用遇到一个很棘手的问题,一直都没能解决,主要问题就是由于有一段程序运行需要挺长的时间,于是就加一个QDialog对象dialog,显示请稍后的信息,然后在这段程序运行前加上dialog->show(),运行结束后加上dialog->close(),运行结果却是有弹窗提示框,但布局的控件没显示,如果注释掉中间的运行很久的程序,弹窗和布局的控件都能正常显示了,真是奇怪,想了很久都没解决,请大家帮忙看看,非常感激。
布局代码为init_dialog:
qDialog->setFixedSize(250,100);
qDialog->setWindowTitle("提示");
QVBoxLayout *DLayout = new QVBoxLayout();
QLabel *label2 = new QLabel();
label2->setText("正在检索,等耐心等待...");
DLayout->addWidget(label2,0,0);
QLabel *label3 = new QLabel();
QMovie *movie = new QMovie(":/image/dialog.gif");
movie->setScaledSize(QSize(230,25));
movie->start();
label3->setMovie(movie);
DLayout->addWidget(label3,1);
qDialog->setLayout(DLayout);
运行代码我就假设了一个需要运行很久的程序放在中间:
QDialog *dialog = new QDialog();
init_dialog(dialog);
dialog->show();
for(int a1=0; a1<20; a1++){
for(int a2=0; a2<10000; a2++){
for(int a3=0; a3<100000; a3++){
if(a2==0 && a3==0)
qDebug() << a1;
}
}
}
dialog->close();
...全文
1393 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
Ethan1994 2015-08-13
  • 打赏
  • 举报
回复
引用 9 楼 huangzi666 的回复:
[quote=引用 8 楼 legend4917 的回复:] [quote=引用 7 楼 huangzi666 的回复:] [quote=引用 6 楼 legend4917 的回复:] [quote=引用 5 楼 huangzi666 的回复:] [quote=引用 4 楼 legend4917 的回复:] [quote=引用 3 楼 huangzi666 的回复:] 应该不会一直阻塞主线程吧,我做的项目里也有一个死循环在另一个线程跑,并不会影响界面的线程。应该是你开线程这些没弄对,你那个耗时操作所在的对象是在哪创建的?你是怎么开线程的,最好把代码贴上来。
我尝试过三种方法,第一次是继承QThread类后重载run方法,将耗时程序放在run里面,但是实验却是能是异步的,不阻塞主线程,后来我遇到在耗时程序中需要用到界面ui的时候,在子线程中是无法使用ui的,百度说要在子线程中发送信号,槽函数在主线程中实现,于是我就在run里面发送信号,耗时程序又搬回主线程中,结果确实能操作主界面ui了,但又不是异步的了,主线程会被阻塞,后来百度自后加了connect中加了第五个参数:Qt::DirectConnection,勉强算是实现了异步功能,不阻塞主线程了,但我总感觉这样不太妥,自己对线程这块才学了点皮毛,嗨[/quote] 我是这样做的,用A类去管理界面显示,用B类去管理这个耗时操作。然后让B类在子线程中跑,通过发送信号给A类显示对应的界面。 大概的代码是这样的:

//A和B都继承QObject
QThread th1;
A a;
B b;
b.moveToThread(&th1);
th1.start();
你试试看能不能解决你的问题[/quote] 但现在的问题是如果在B类中处理耗时程序的话,由于耗时程序需要进行ui操作,而ui操作只能在A类中进行,怎么办呢?[/quote]利用信号的槽啊,B可以发射信号并传递参数过去,A中的槽函数对参数进行判断显示相应的界面。。。比如参数是1,就显示窗口,参数是2就隐藏窗口。不知道这样说明白吗?[/quote] 我懂你什么意思,我简单描述一下我的问题吧,我需要用QTableWidget显示数据量达到7000行的数据,每次刷新会比较忙,大概要10秒,而且会阻塞主线程,造成假死现象,因此我想让刷新的程序放进一个子线程中去运行,主线程在子线程开始的时候在QTableWidget区域覆盖一个动图,表示正在刷新,等待子线程运行完毕之后再关闭这个动图,表示刷新完毕,由于放进子线程的程序要用到主线程中的QTableWidget对象,不断添加数据,我只能在子线程中发送信号,槽函数还是要运行在主线程中才能在QTableWidget中添加数据啊,你说的那个方法我不知道怎么用进去。。。[/quote] 原来是这样,那我说的方法就不适用了。。。既然你的方法可以实现功能,就先别管吧,以后对线程理解了再改,我对线程也不是很理解。把QTableWidget弄成全局的有没有可能?[/quote] 现在所有的问题处理的差不多了,参加比赛临时上手Qt也是蛮拼的,估计比赛结束之后就不会再碰Qt了。。。
huangzi666 2015-08-12
  • 打赏
  • 举报
回复
引用 6 楼 legend4917 的回复:
[quote=引用 5 楼 huangzi666 的回复:] [quote=引用 4 楼 legend4917 的回复:] [quote=引用 3 楼 huangzi666 的回复:] 应该不会一直阻塞主线程吧,我做的项目里也有一个死循环在另一个线程跑,并不会影响界面的线程。应该是你开线程这些没弄对,你那个耗时操作所在的对象是在哪创建的?你是怎么开线程的,最好把代码贴上来。
我尝试过三种方法,第一次是继承QThread类后重载run方法,将耗时程序放在run里面,但是实验却是能是异步的,不阻塞主线程,后来我遇到在耗时程序中需要用到界面ui的时候,在子线程中是无法使用ui的,百度说要在子线程中发送信号,槽函数在主线程中实现,于是我就在run里面发送信号,耗时程序又搬回主线程中,结果确实能操作主界面ui了,但又不是异步的了,主线程会被阻塞,后来百度自后加了connect中加了第五个参数:Qt::DirectConnection,勉强算是实现了异步功能,不阻塞主线程了,但我总感觉这样不太妥,自己对线程这块才学了点皮毛,嗨[/quote] 我是这样做的,用A类去管理界面显示,用B类去管理这个耗时操作。然后让B类在子线程中跑,通过发送信号给A类显示对应的界面。 大概的代码是这样的:

//A和B都继承QObject
QThread th1;
A a;
B b;
b.moveToThread(&th1);
th1.start();
你试试看能不能解决你的问题[/quote] 但现在的问题是如果在B类中处理耗时程序的话,由于耗时程序需要进行ui操作,而ui操作只能在A类中进行,怎么办呢?[/quote]利用信号的槽啊,B可以发射信号并传递参数过去,A中的槽函数对参数进行判断显示相应的界面。。。比如参数是1,就显示窗口,参数是2就隐藏窗口。不知道这样说明白吗?
Ethan1994 2015-08-12
  • 打赏
  • 举报
回复
引用 5 楼 huangzi666 的回复:
[quote=引用 4 楼 legend4917 的回复:] [quote=引用 3 楼 huangzi666 的回复:] 应该不会一直阻塞主线程吧,我做的项目里也有一个死循环在另一个线程跑,并不会影响界面的线程。应该是你开线程这些没弄对,你那个耗时操作所在的对象是在哪创建的?你是怎么开线程的,最好把代码贴上来。
我尝试过三种方法,第一次是继承QThread类后重载run方法,将耗时程序放在run里面,但是实验却是能是异步的,不阻塞主线程,后来我遇到在耗时程序中需要用到界面ui的时候,在子线程中是无法使用ui的,百度说要在子线程中发送信号,槽函数在主线程中实现,于是我就在run里面发送信号,耗时程序又搬回主线程中,结果确实能操作主界面ui了,但又不是异步的了,主线程会被阻塞,后来百度自后加了connect中加了第五个参数:Qt::DirectConnection,勉强算是实现了异步功能,不阻塞主线程了,但我总感觉这样不太妥,自己对线程这块才学了点皮毛,嗨[/quote] 我是这样做的,用A类去管理界面显示,用B类去管理这个耗时操作。然后让B类在子线程中跑,通过发送信号给A类显示对应的界面。 大概的代码是这样的:

//A和B都继承QObject
QThread th1;
A a;
B b;
b.moveToThread(&th1);
th1.start();
你试试看能不能解决你的问题[/quote] 但现在的问题是如果在B类中处理耗时程序的话,由于耗时程序需要进行ui操作,而ui操作只能在A类中进行,怎么办呢?
huangzi666 2015-08-12
  • 打赏
  • 举报
回复
引用 4 楼 legend4917 的回复:
[quote=引用 3 楼 huangzi666 的回复:] 应该不会一直阻塞主线程吧,我做的项目里也有一个死循环在另一个线程跑,并不会影响界面的线程。应该是你开线程这些没弄对,你那个耗时操作所在的对象是在哪创建的?你是怎么开线程的,最好把代码贴上来。
我尝试过三种方法,第一次是继承QThread类后重载run方法,将耗时程序放在run里面,但是实验却是能是异步的,不阻塞主线程,后来我遇到在耗时程序中需要用到界面ui的时候,在子线程中是无法使用ui的,百度说要在子线程中发送信号,槽函数在主线程中实现,于是我就在run里面发送信号,耗时程序又搬回主线程中,结果确实能操作主界面ui了,但又不是异步的了,主线程会被阻塞,后来百度自后加了connect中加了第五个参数:Qt::DirectConnection,勉强算是实现了异步功能,不阻塞主线程了,但我总感觉这样不太妥,自己对线程这块才学了点皮毛,嗨[/quote] 我是这样做的,用A类去管理界面显示,用B类去管理这个耗时操作。然后让B类在子线程中跑,通过发送信号给A类显示对应的界面。 大概的代码是这样的:

//A和B都继承QObject
QThread th1;
A a;
B b;
b.moveToThread(&th1);
th1.start();
你试试看能不能解决你的问题
Ethan1994 2015-08-12
  • 打赏
  • 举报
回复
引用 3 楼 huangzi666 的回复:
应该不会一直阻塞主线程吧,我做的项目里也有一个死循环在另一个线程跑,并不会影响界面的线程。应该是你开线程这些没弄对,你那个耗时操作所在的对象是在哪创建的?你是怎么开线程的,最好把代码贴上来。
我尝试过三种方法,第一次是继承QThread类后重载run方法,将耗时程序放在run里面,但是实验却是能是异步的,不阻塞主线程,后来我遇到在耗时程序中需要用到界面ui的时候,在子线程中是无法使用ui的,百度说要在子线程中发送信号,槽函数在主线程中实现,于是我就在run里面发送信号,耗时程序又搬回主线程中,结果确实能操作主界面ui了,但又不是异步的了,主线程会被阻塞,后来百度自后加了connect中加了第五个参数:Qt::DirectConnection,勉强算是实现了异步功能,不阻塞主线程了,但我总感觉这样不太妥,自己对线程这块才学了点皮毛,嗨
huangzi666 2015-08-12
  • 打赏
  • 举报
回复
引用 8 楼 legend4917 的回复:
[quote=引用 7 楼 huangzi666 的回复:] [quote=引用 6 楼 legend4917 的回复:] [quote=引用 5 楼 huangzi666 的回复:] [quote=引用 4 楼 legend4917 的回复:] [quote=引用 3 楼 huangzi666 的回复:] 应该不会一直阻塞主线程吧,我做的项目里也有一个死循环在另一个线程跑,并不会影响界面的线程。应该是你开线程这些没弄对,你那个耗时操作所在的对象是在哪创建的?你是怎么开线程的,最好把代码贴上来。
我尝试过三种方法,第一次是继承QThread类后重载run方法,将耗时程序放在run里面,但是实验却是能是异步的,不阻塞主线程,后来我遇到在耗时程序中需要用到界面ui的时候,在子线程中是无法使用ui的,百度说要在子线程中发送信号,槽函数在主线程中实现,于是我就在run里面发送信号,耗时程序又搬回主线程中,结果确实能操作主界面ui了,但又不是异步的了,主线程会被阻塞,后来百度自后加了connect中加了第五个参数:Qt::DirectConnection,勉强算是实现了异步功能,不阻塞主线程了,但我总感觉这样不太妥,自己对线程这块才学了点皮毛,嗨[/quote] 我是这样做的,用A类去管理界面显示,用B类去管理这个耗时操作。然后让B类在子线程中跑,通过发送信号给A类显示对应的界面。 大概的代码是这样的:

//A和B都继承QObject
QThread th1;
A a;
B b;
b.moveToThread(&th1);
th1.start();
你试试看能不能解决你的问题[/quote] 但现在的问题是如果在B类中处理耗时程序的话,由于耗时程序需要进行ui操作,而ui操作只能在A类中进行,怎么办呢?[/quote]利用信号的槽啊,B可以发射信号并传递参数过去,A中的槽函数对参数进行判断显示相应的界面。。。比如参数是1,就显示窗口,参数是2就隐藏窗口。不知道这样说明白吗?[/quote] 我懂你什么意思,我简单描述一下我的问题吧,我需要用QTableWidget显示数据量达到7000行的数据,每次刷新会比较忙,大概要10秒,而且会阻塞主线程,造成假死现象,因此我想让刷新的程序放进一个子线程中去运行,主线程在子线程开始的时候在QTableWidget区域覆盖一个动图,表示正在刷新,等待子线程运行完毕之后再关闭这个动图,表示刷新完毕,由于放进子线程的程序要用到主线程中的QTableWidget对象,不断添加数据,我只能在子线程中发送信号,槽函数还是要运行在主线程中才能在QTableWidget中添加数据啊,你说的那个方法我不知道怎么用进去。。。[/quote] 原来是这样,那我说的方法就不适用了。。。既然你的方法可以实现功能,就先别管吧,以后对线程理解了再改,我对线程也不是很理解。把QTableWidget弄成全局的有没有可能?
Ethan1994 2015-08-12
  • 打赏
  • 举报
回复
引用 7 楼 huangzi666 的回复:
[quote=引用 6 楼 legend4917 的回复:] [quote=引用 5 楼 huangzi666 的回复:] [quote=引用 4 楼 legend4917 的回复:] [quote=引用 3 楼 huangzi666 的回复:] 应该不会一直阻塞主线程吧,我做的项目里也有一个死循环在另一个线程跑,并不会影响界面的线程。应该是你开线程这些没弄对,你那个耗时操作所在的对象是在哪创建的?你是怎么开线程的,最好把代码贴上来。
我尝试过三种方法,第一次是继承QThread类后重载run方法,将耗时程序放在run里面,但是实验却是能是异步的,不阻塞主线程,后来我遇到在耗时程序中需要用到界面ui的时候,在子线程中是无法使用ui的,百度说要在子线程中发送信号,槽函数在主线程中实现,于是我就在run里面发送信号,耗时程序又搬回主线程中,结果确实能操作主界面ui了,但又不是异步的了,主线程会被阻塞,后来百度自后加了connect中加了第五个参数:Qt::DirectConnection,勉强算是实现了异步功能,不阻塞主线程了,但我总感觉这样不太妥,自己对线程这块才学了点皮毛,嗨[/quote] 我是这样做的,用A类去管理界面显示,用B类去管理这个耗时操作。然后让B类在子线程中跑,通过发送信号给A类显示对应的界面。 大概的代码是这样的:

//A和B都继承QObject
QThread th1;
A a;
B b;
b.moveToThread(&th1);
th1.start();
你试试看能不能解决你的问题[/quote] 但现在的问题是如果在B类中处理耗时程序的话,由于耗时程序需要进行ui操作,而ui操作只能在A类中进行,怎么办呢?[/quote]利用信号的槽啊,B可以发射信号并传递参数过去,A中的槽函数对参数进行判断显示相应的界面。。。比如参数是1,就显示窗口,参数是2就隐藏窗口。不知道这样说明白吗?[/quote] 我懂你什么意思,我简单描述一下我的问题吧,我需要用QTableWidget显示数据量达到7000行的数据,每次刷新会比较忙,大概要10秒,而且会阻塞主线程,造成假死现象,因此我想让刷新的程序放进一个子线程中去运行,主线程在子线程开始的时候在QTableWidget区域覆盖一个动图,表示正在刷新,等待子线程运行完毕之后再关闭这个动图,表示刷新完毕,由于放进子线程的程序要用到主线程中的QTableWidget对象,不断添加数据,我只能在子线程中发送信号,槽函数还是要运行在主线程中才能在QTableWidget中添加数据啊,你说的那个方法我不知道怎么用进去。。。
huangzi666 2015-08-10
  • 打赏
  • 举报
回复
应该不会一直阻塞主线程吧,我做的项目里也有一个死循环在另一个线程跑,并不会影响界面的线程。应该是你开线程这些没弄对,你那个耗时操作所在的对象是在哪创建的?你是怎么开线程的,最好把代码贴上来。
Ethan1994 2015-08-09
  • 打赏
  • 举报
回复
谢谢指导,我试着将耗时代码用一个线程去执行,由于耗时代码还要用到控件对象,因此我只能在使用信号槽的机制,在线程run的重载函数里emit一个信号,耗时代码接收信号并开始执行,结果还是会阻塞主程序。。。头痛。。。
wafstudio 2015-08-08
  • 打赏
  • 举报
回复
你这是在一个线程里,运行耗时代码时dialog的就不处理了。 可以把耗时代码放到一个线程中,当处理完时再通知dialog。

16,173

社区成员

发帖
与我相关
我的任务
社区描述
Qt 是一个跨平台应用程序框架。通过使用 Qt,您可以一次性开发应用程序和用户界面,然后将其部署到多个桌面和嵌入式操作系统,而无需重复编写源代码。
社区管理员
  • Qt
  • 亭台六七座
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧