• 11696阅读
  • 52回复

[提问]如何让两个button的槽函数一个先执行,一个后执行呢? [复制链接]

上一主题 下一主题
离线foxgod
 

只看楼主 正序阅读 楼主  发表于: 2013-10-24
我现在有两个button,每个button都有一个槽函数,第一个button的槽函数的执行需要一些时间,我想做的是,第一个button还没有执行完的时候,我点击第二个button,就不执行第二个button里面的槽函数,我不想使用变量才判断,可以使用event来实现吗?我使用QCoreApplication::postEvent().貌似没有作用。


代码如何::
代码 code.rar (3 K) 下载次数:10








离线alexltr

只看该作者 52楼 发表于: 2013-11-05
If several slots are connected to one signal, the slots will be executed one after the other, in the order they have been connected, when the signal is emitted.

詳細請閱讀Qt文檔"Signals & Slots"
我不从事IT,只是喜欢Qt。
我不是程序员,只是与程序有缘。
我写程序,只是为了让工作变得简单有序!

                      ----  一个一直在入门的编程学习者
离线foxgod

只看该作者 51楼 发表于: 2013-11-05
回 49楼(alexltr) 的帖子
再问个问题,同一个信号对应多个槽函数,这个槽函数执行的顺序是怎么样的呢
离线foxgod

只看该作者 50楼 发表于: 2013-11-05
回 49楼(alexltr) 的帖子
你修改的正好是我想要的,谢谢,因为我一直不知道QApplication::processEvents();的意义。
离线alexltr

只看该作者 49楼 发表于: 2013-11-04
1. 你有提供代码,但你的代码不能很明显的重现你的问题。
2. 你的代码是有设置一个判断值,但你的判断标准是什么?
    在什么情况下是true;什么情况下转换为false?
    按照你的代码, 第一次执行后永远也无法恢复回原来的状态。
    我认为你的代码的结构和算法有问题。


按照我的理解,或是对你的问题的猜想,对你的代码稍做了修改,并加了一个耗时的操作,以重现你的问题。请看附件。
但我觉得3楼的方法就可以实现这样的效果。 code Revised.zip (4 K) 下载次数:11
我不从事IT,只是喜欢Qt。
我不是程序员,只是与程序有缘。
我写程序,只是为了让工作变得简单有序!

                      ----  一个一直在入门的编程学习者
离线rpdhunter

只看该作者 48楼 发表于: 2013-11-04
我下载了楼主的例子,很简单的一个程序啊,毫无问题,无论怎么点都不会出现崩溃的情况,楼主,是不是你电脑有问题
离线dbzhang800

只看该作者 47楼 发表于: 2013-11-04
Re:回 45楼(dbzhang800) 的帖子
引用第46楼foxgod于2013-11-04 11:14发表的 回 45楼(dbzhang800) 的帖子 :
哥们,我想哭,我的demo就是我的小例子,只要你能把我的demo做成我要的效果,就OK了,我没有别的demo,只是想这样做。不存在我方向错误。我只是想在我的demo里面做成这样。


好吧,咱们回头看看你的问题?

在顶楼中,你如是说:

我现在有两个button,每个button都有一个槽函数,第一个button的槽函数的执行需要一些时间,我想做的是,第一个button还没有执行完的时候,我点击第二个button,就不执行第二个button里面的槽函数


在43楼中,你如是说:

我一直没有说,在button的槽执行中再次执行了别的槽函数,我一直说的是在button执行完又再次执行了别的槽函数,但是我想拦截别的槽函数,估计你一直没理解我。


现在有两个问题:
1. 大家不明白你遇到的是什么问题
2. 大家不明白你要的具体是什么效果
离线foxgod

只看该作者 46楼 发表于: 2013-11-04
回 45楼(dbzhang800) 的帖子
哥们,我想哭,我的demo就是我的小例子,只要你能把我的demo做成我要的效果,就OK了,我没有别的demo,只是想这样做。不存在我方向错误。我只是想在我的demo里面做成这样。
离线dbzhang800

只看该作者 45楼 发表于: 2013-11-04
重现问题并不需要太多代码,一个完整的程序可能只有几行代码

比如,bug25985

https://bugreports.qt-project.org/browse/QTBUG-25985

在比如,qmake遇到一个pro文件会失败
https://bugreports.qt-project.org/browse/QTBUG-27629

在能重现问题的情况下,代码越少对定位问题越有效。

通常找到问题是最困难的,一旦找到问题,解决问题往往很简单。
离线dbzhang800

只看该作者 44楼 发表于: 2013-11-04
;-) 你这个帖子在qtcn和qt-project.org中都有些日子了。


所以才要你给出例子嘛,因为不止我不理解,论坛中其他同胞也都没有理解。不止国内同胞没理解,qt-project.org/forums 中的国外开发者也没有理解。

---
很可能你遇到问题的程序,代码量比较大。但是你想确定问题是不是和你认为的一样,你需要一个小程序来重新问题才行。而一旦你可以重现问题。无论是在论坛提问,还是去提交bug,应该都很容易解决问题。

如果不能重现问题,通常是你先入为主,找错方向了。
离线foxgod

只看该作者 43楼 发表于: 2013-11-04
回 40楼(dbzhang800) 的帖子
我一直没有说,在button的槽执行中再次执行了别的槽函数,我一直说的是在button执行完又再次执行了别的槽函数,但是我想拦截别的槽函数,估计你一直没理解我。
离线foxgod

只看该作者 42楼 发表于: 2013-11-04

哥们,我没有说在槽函数执行过程中执行了别的操作,是说我在点击5次button的时候,这五次信号被保存在队列里面,第一次button的槽函数执行完,又执行第二次button的槽函数执行,接着是第三次,四次,五次,可是我只想第一次槽函数执行完,就不执行第二次,第三次,第四次槽函数的执行,当然你们可以说设置一个bool变量去判断,可是第一次槽函数执行完,去设置bool为true,这样可以阻止其他操再次执行,可是这样一来,你只是阻止了第一次连续点击五次button的,其他四次button的执行,加入我在次连续点击五次button,就不不起作用了。
比如下面。


  1. void Widget::setBackground(QObject *obj)
  2. {
  3.      switch(obj->objectName().toInt())
  4.     {  
  5.     case 0:
  6. m_judge = true;
  7.         if(m_judge = true)
  8.         {
  9.             qDebug()<<"enter button0";
  10.             m_judge = false ;
  11.         }
  12.         else
  13.         {
  14.             qDebug()<<"don't enter button0";            
  15.         }
  16.         
  17.         break;
  18.     case 1:
  19.         qDebug()<<"enter button1";
  20.        break;
  21.     case 2:
  22.        qDebug()<<"enter button2";
  23.        break;
  24.     }
  25. }
               这样第一次可以阻止其他四次button的点击,但是你再次;连续点击5此button就不可以执行了,对不


离线alexltr

只看该作者 41楼 发表于: 2013-11-02
你的button是不是设置了autorepeat属性? 要不然槽函数在执行过程中是不可能响应其它事件的。如果autorepeat为true,槽函数又没有完成,这时连续点击就会崩溃
我不从事IT,只是喜欢Qt。
我不是程序员,只是与程序有缘。
我写程序,只是为了让工作变得简单有序!

                      ----  一个一直在入门的编程学习者
离线dbzhang800

只看该作者 40楼 发表于: 2013-11-01
Re:回 37楼(dbzhang800) 的帖子
引用第39楼foxgod于2013-11-01 17:15发表的 回 37楼(dbzhang800) 的帖子 :
我现在的情况是什么呢,就是连续点击button,消息堆积在队列里面,不知道什么原因造成了崩溃,当然可能不是信号和槽的问题,但是我就是不想消息推挤,就是想在队列里面有5个消息,我就执行一个消息。后面其他的都不执行,也就是我button1点击后,后面所有的都不执行,比如鼠标事件,移动事件,button2 ,button3触发事件,我都要屏蔽,不执行了。我想我这次说明白了吧,我的代码就是看看怎么样可以屏蔽。


问题在于:Qt默认的就是你所期待的效果。而且你也没有给出一个能重现你所提到的问题的简单例子。

所以最可能的就是:你解决问题的方向错了。


离线foxgod

只看该作者 39楼 发表于: 2013-11-01
回 37楼(dbzhang800) 的帖子
我现在的情况是什么呢,就是连续点击button,消息堆积在队列里面,不知道什么原因造成了崩溃,当然可能不是信号和槽的问题,但是我就是不想消息推挤,就是想在队列里面有5个消息,我就执行一个消息。后面其他的都不执行,也就是我button1点击后,后面所有的都不执行,比如鼠标事件,移动事件,button2 ,button3触发事件,我都要屏蔽,不执行了。我想我这次说明白了吧,我的代码就是看看怎么样可以屏蔽。

离线dbzhang800

只看该作者 38楼 发表于: 2013-11-01
可能是想要的只是一个很简单的东西,可是你自己把它们想复杂了。
离线dbzhang800

只看该作者 37楼 发表于: 2013-11-01
恩,代码看到了。建议你好好理理自己的思路,你的目的是什么。

程序执行是受你的代码控制的,但是你的代码可能并不是你想表达的。

-----

不妨假象自己不懂程序,只是个用户。从用户的角度来描述,你想要程序做什么。(不要提信号、槽、等等概念)。

比如说,点击按钮1之后,其后10s内,忽略任何键盘和鼠标操作(除非点击xxx,或10s时间到)。等等
离线foxgod

只看该作者 36楼 发表于: 2013-11-01
回 35楼(dbzhang800) 的帖子
代码我已经上传了。点击下面的button,上面的button是我在界面上拖出来的。
离线dbzhang800

只看该作者 35楼 发表于: 2013-11-01
Re:回 33楼(dbzhang800) 的帖子
引用第34楼foxgod于2013-11-01 16:03发表的 回 33楼(dbzhang800) 的帖子 :
大哥你QQ多少,我觉得我的例子和我说的都很明显了呀
我的例子也就是写log,没啥,只要你能把我上面写的signalmap的槽函数里面,可以按照我说的阻止完后,在恢复就可以了,我没有别的要求。


所以才要你给出完整的例子嘛。因为你觉得你说明白了,但是其他人都还是一头雾水。

只需要一个几十行的例子就行了,一个 main.cpp 足够,连 .pro 文件都不需要。保证其他人只要
qmake -project
qmake
make
就可运行即可。

---

离线foxgod

只看该作者 34楼 发表于: 2013-11-01
回 33楼(dbzhang800) 的帖子
大哥你QQ多少,我觉得我的例子和我说的都很明显了呀
我的例子也就是写log,没啥,只要你能把我上面写的signalmap的槽函数里面,可以按照我说的阻止完后,在恢复就可以了,我没有别的要求。


离线dbzhang800

只看该作者 33楼 发表于: 2013-11-01
还是我前面说的,不妨用几十行代码写个完整的 可编译运行的可以体现出你的问题所在的例子。然后发出来

不然,估计大家都不明白你到底是在哪儿遇到了问题,遇到了什么问题。
离线foxgod

只看该作者 32楼 发表于: 2013-11-01
回 26楼(friendbaby) 的帖子
看看我的答案吧,
离线foxgod

只看该作者 31楼 发表于: 2013-11-01
回 30楼(dbzhang800) 的帖子
问题依旧存在,你可以试验下。
我最开始就是什么都不写。也曾经实验过Qt::DirectConnection,都不可以。
离线dbzhang800

只看该作者 30楼 发表于: 2013-11-01
你把 Qt::QueuedConnection 去掉,你说的这些问题不就都没了么?
离线foxgod

只看该作者 29楼 发表于: 2013-11-01
  1. Widget::Widget(QWidget *parent) :
  2.     QWidget(parent),
  3.     ui(new Ui::Widget)
  4. {
  5.     ui->setupUi(this);  
  6.     signalMapper = new QSignalMapper(this);
  7.     for (int i = 0; i < 3; i++)
  8.     {
  9.         QPushButton *button = new QPushButton(this);
  10.         button->setObjectName(QString::number(i));
  11.         connect(button, SIGNAL(pressed()), signalMapper, SLOT(map()),Qt::QueuedConnection);//原始信号传递给signalmapper
  12.         signalMapper->setMapping(button, (QObject*)button);
  13.     }
  14.     connect(signalMapper,SIGNAL(mapped(QObject*)),this,SLOT(setBackground(QObject*)),Qt::QueuedConnection);
  15. }
  16. 这里我将多个button用signalMapper来管理。
  17. void Widget::setBackground(QObject *obj)
  18. {
  19.     qDebug()<<"setBackground";
  20.     myobject mobj;
  21.     switch(obj->objectName())
  22.     {
  23.     case 0:
  24.         qDebug()<<"enter button0";
  25.         break;
  26.     case 1:
  27.         qDebug()<<"enter button1";
  28.        break;
  29.     case 2:
  30.        qDebug()<<"enter button2";
  31.        break;
  32.     }
  33. }
我现在的情况是连续多次点击button1,那么现在点击的信号在队列里面一个个的执行。(假设现在点击了五次,那么就要执行五次),可是我只想执行一次(也就是在button1执行完后,在消息队列里面的其他信号要执行的槽函数我不想执行了),我如果设置一个bool变量来判断的话,让他第一次点击执行完变为true,这样可以阻止其他4次的点击,可是我什么时候恢复这个变量呢,如果第一次button执行完就恢复,那么其他4次还是执行了,没有起到作用,如果不恢复这个bool变量,那么在次点击这个button1,永远都不起作用了。我的效果是连续点击button1,假设点了5次,我只想执行一次,其他4次不执行,然后再等一秒,我再次连续5次点击button1,还是可以只执行一次,其他4次不执行。



第二种情况,如果我点击了button1,button2,button3,那么我想让button1执行,其他button不执行。或是点击顺序为button2,button1,button3那么我想让button2执行,其他button不执行。,可是这也遇到了一个情况,你设置一个bool变量可以阻止其他button执行,可是什么时候恢复这个bool变量呢,如果你在一个button执行完的时候恢复这个变量,相当于没有阻止其他button执行,求指教。我的效果是点击button1,button2,button3,我只想执行button1一次,其他button不执行,然后再等一秒,我再次点击button2,button3,button1,这次我只想button2执行,其他的不执行,也就是每次只执行首先点击的button,其他button不执行。


现在的问题是如何阻止其他button执行的问题,第二个是如何恢复的问题。
求指教


离线dbzhang800

只看该作者 28楼 发表于: 2013-11-01
不妨用几十行代码写个完整的可编译运行的,可以体现出你的问题所在的例子。然后发出来

不然,估计大家都不明白你到底是在哪儿遇到了问题,遇到了什么问题。
离线foxgod

只看该作者 27楼 发表于: 2013-10-31
回 26楼(friendbaby) 的帖子
那就是我不能屏蔽第二个不button的信号了吗,我想问下,我们的事件在一个队列里面,一个个执行,那么我们的信号在那里放着呢,是和事件在一个队列里面放的吗,如果在一个队列里面放着,我如何执行完第一个,就不执行后面的呢
离线friendbaby

只看该作者 26楼 发表于: 2013-10-30
这里不存在消息队列,因为这不是多线程
Smiling is best language , can express everything , also can conceal everything.
离线friendbaby

只看该作者 25楼 发表于: 2013-10-30
Qt::DirectConnection 会直接跳到槽函数去执行,楼主可以调试一下。
你在第一个槽函数里面写一个死循环,界面会死掉。根本无法点击第二个按钮。
Smiling is best language , can express everything , also can conceal everything.
离线friendbaby

只看该作者 24楼 发表于: 2013-10-30
单线程,是不会同时执行两个函数的。
Smiling is best language , can express everything , also can conceal everything.
离线dbzhang800

只看该作者 23楼 发表于: 2013-10-29
引用第21楼foxgod于2013-10-28 17:51发表的  :
Qt::DirectConnection这种方式连接的话,是不是也是在消息队列里面,按照先进先出的顺序执行槽函数。

这种情况下,不涉及Qt的事件队列。但既然你用过MFC,对系统底层应该比我清楚,键鼠事件等都会进入系统的消息队列。Qt作为一个库,处理的也只是系统派发的消息,至于这中间,Qt会不会有bug,需要你来验证。
离线foxgod

只看该作者 22楼 发表于: 2013-10-28
回 20楼(dbzhang800) 的帖子
你知道如何获取消息队列里面的东西吗
离线foxgod

只看该作者 21楼 发表于: 2013-10-28
Qt::DirectConnection这种方式连接的话,是不是也是在消息队列里面,按照先进先出的顺序执行槽函数。
离线dbzhang800

只看该作者 20楼 发表于: 2013-10-28
引用第19楼foxgod于2013-10-28 17:06发表的  :
我在QT帮助时,在connect中的第五个参数,如果是Qt::DirectConnection,那么他是直连,对这个参数,我理解是点击一个不button就去执行槽函数,不存在等待时间(不知道我理解的对不),



引用第19楼foxgod于2013-10-28 17:06发表的  :
你说的点击完一个button后,不能再次点击别的button,为什么不能点击,

我上一个帖子说的就是这个问题的答案。你写个简单的小程序应该就能测试。
引用第19楼foxgod于2013-10-28 17:06发表的  :
我这里测试就是不停的连续的点击我多个button,导致了崩溃。

所以你需要调试你的程序,而不是纠结于假象的问题。
离线foxgod

只看该作者 19楼 发表于: 2013-10-28
我在QT帮助时,在connect中的第五个参数,如果是Qt::DirectConnection,那么他是直连,对这个参数,我理解是点击一个不button就去执行槽函数,不存在等待时间(不知道我理解的对不),你说的点击完一个button后,不能再次点击别的button,为什么不能点击,我这里测试就是不停的连续的点击我多个button,导致了崩溃。




离线dbzhang800

只看该作者 18楼 发表于: 2013-10-28
第一个button的槽函数执行完之前,你不可能再次点中本button点中其他button。你应该了解,在执行耗时操作时,界面是死掉的。同样,执行不耗时的操作时,界面也是死掉的,只是时间短,我们感觉不到而已。
离线foxgod

只看该作者 17楼 发表于: 2013-10-28
回 16楼(dbzhang800) 的帖子
我想问版主,QT的默认行为就是点击一个button然后进入消息队列,等待第一个不button的槽函数执行完,然后执行第二个button的槽函数,难道我不可以在第一个button的槽函数执行完,阻止第二个button的槽函数执行。MFC都可以,我相信QT也可以
离线dbzhang800

只看该作者 16楼 发表于: 2013-10-28
Re:回 14楼(dbzhang800) 的帖子
引用第15楼foxgod于2013-10-28 16:05发表的 回 14楼(dbzhang800) 的帖子 :
连续快速点击对个button,只有第一个button执行,其他button不执行,当第一个button执行完后,恢复初始状态
如果再次连续点击多个button,如果这个第二个button先被点击,则第二个button执行,其他button不执行,
.......

这是Qt的默认行为,不需要任何特殊操作。除非你发现Qt的一个bug(如果你可以通过一个小例子来重现问题,即可去提交Bug)。

至于你遇到的问题,你不妨好好调试你的程序,看看问题出在什么地方。
离线foxgod

只看该作者 15楼 发表于: 2013-10-28
回 14楼(dbzhang800) 的帖子
我刚才贴的代码,确实是只执行了button1,其他两个button没有执行,但是我的程序需要这样做,连续快速点击对个button,只有第一个button执行,其他button不执行,当第一个button执行完后,恢复初始状态


如果再次连续点击多个button,如果这个第二个button先被点击,则第二个button执行,其他button不执行,
但是现在我贴上去的代码,只有第一个点击多个button正常,第二个点击多个就不起作用了
离线dbzhang800

只看该作者 14楼 发表于: 2013-10-28
你给的代码不可能出现你描述的问题。不需要任何玩外操作,也是一个执行完按钮动作,再执行的另外一个。不会出现当前槽执行期间响应其他按钮的问题。

要么你贴的代码和你用的不一致。要么你感到疑惑的这个问题其实本就不存在。
快速回复
限100 字节
 
上一个 下一个