• 9853阅读
  • 12回复

[提问]如何实现界面上的关闭按钮?(已解决) [复制链接]

上一主题 下一主题
离线liuxu_lx7
 
只看楼主 倒序阅读 楼主  发表于: 2011-06-13
响应QPushButton的clicked()信号,在对应的槽中 delete 按钮所在控件。 结果程序崩溃:

明显是:delete内存在前, 按钮的ReleaseMouse操作在后, 导致崩溃。
如果不是响应clicked()信号, 应该响应什么呢?

离线guuyan

只看该作者 1楼 发表于: 2011-06-13
那就响应release信号就是了
离线jdwx

只看该作者 2楼 发表于: 2011-06-13
你是说在界面上放一个关闭按钮,见QT的第一个例子。
发帖时要说明:操作系统、Qt版本、编译器,这样能更快的得到回复。
离线liuxu_lx7
只看该作者 3楼 发表于: 2011-06-13
回 1楼(guuyan) 的帖子
试过了,不行
离线liuxu_lx7
只看该作者 4楼 发表于: 2011-06-13
回 2楼(jdwx) 的帖子
谢谢提供参考,我现在看
离线liuxu_lx7
只看该作者 5楼 发表于: 2011-06-13
回 4楼(liuxu_lx7) 的帖子
看了下,例子中,关闭按钮都是 QAction.
代码:
     QAction *exitAction = new QAction(tr("Exit"), this);
     exitAction->setSoftKeyRole(QAction::NegativeSoftKey);
     connect (exitAction, SIGNAL(triggered()),this, SLOT(close()));
     addAction (exitAction);

而我的是个QPushButton,我是要用在QGraphicsScene中的,并且需要重新设置位置(QAction没有重设位置的函数)
离线jdwx

只看该作者 6楼 发表于: 2011-06-13
我有点不理解你的意思了,是不是就是点一个按钮关闭对画框?
如果是,其实不用写代码,在信号和槽编辑器里把QPushButton的clicked()和QDialog的close()连接起来就可以。
发帖时要说明:操作系统、Qt版本、编译器,这样能更快的得到回复。
离线liuxu_lx7
只看该作者 7楼 发表于: 2011-06-14
回 6楼(jdwx) 的帖子
我需要在 QGraphicsScene中画一个矩形,创建QPushButton并添加到QGraphicsScene, 然后再通过setParentItem设置成为矩形的子。要求点击QPushButton后,删除这个矩形

运行结果:响应QPushButton的clicked事件后(released也一样), 删除这个矩形, 程序崩溃。

因为:先释放QPushButton,之后QT机制又处理了QPushButton的鼠标事件。

猜测的解决方案:QPushButton应该有接口可以安全销毁自身(调用后会立即清除事件堆栈中相关信息)。不知道是否有这个接口,又或者有其他机制来解决这个问题?
离线cutemmll
只看该作者 8楼 发表于: 2011-06-14
曾经我也做过一次测试,如果在关联自身的槽函数里面做删除自身的操作,一定会crash。
至于原因,我没有去深究过,也就是说如果你有下面的connect函数调用
  1. connect(myObj,SIGNAL(someSignal()),this,SLOT(deleteMyObj()));

如果在deleteMyObj()函数中进行删除myObj相关的操作,那么程序一定会crash,不管你是调用的delete操作符,还是调用deletelater()函数,都会crash。

当时我的处理办法是在deleteMyObj()中增加一个QTimer做一个延迟调用,进行删除相关的操作,deleteMyObj()函数实现如下:
  1. void MyClass::deleteMyObj()
  2. {
  3.     myObj->hide(); //可以先隐藏该控件
  4.     QTimer::singleShot(500,this,SLOT(deleteMyObjOperate()));
  5. }
  6. void MyClass::deleteMyObjOperate()
  7. {
  8.     myObj->deleteLater(); //做删除该控件的操作
  9. }

也许会有更好的办法,你可尝试一下。

c------------enjoy qt & enjoy life-----------++
离线liuxu_lx7
只看该作者 9楼 发表于: 2011-06-14
回 8楼(cutemmll) 的帖子
“先隐藏后删除”是个办法,可2操作之间的时间差,又需要有额外的代码维护,也是麻烦事。(有的项目也许不需要维护)。

(我还没研究计时器这东西)

还有,给多少时间合适也是个问题,如果设置延迟时间为1毫秒不会崩溃,那还能用,否则,给多少时间都有可能在机器极其慢的时候崩溃吧。

在此感谢您的回复
离线cutemmll
只看该作者 10楼 发表于: 2011-06-14
回 9楼(liuxu_lx7) 的帖子
你提到的问题需要你自己去测试了,deleteLater()会在退出事件循环时才进行删除操作。如果不是批量重复删除多个控件,采用这种办法应该是可行的。
如果你有时间的话,可以写个小程序debug一下,看看程序崩溃的原因,这样你就可以准确地对你的问题做出解答了。
c------------enjoy qt & enjoy life-----------++
离线liuxu_lx7
只看该作者 11楼 发表于: 2011-06-14
回 10楼(cutemmll) 的帖子
deleteLater() 我试试,谢谢啦。

想深入了解Qt,时间确实紧。
离线liuxu_lx7
只看该作者 12楼 发表于: 2011-06-14
回 11楼(liuxu_lx7) 的帖子
deleteLater() 果然解决问题啦
快速回复
限100 字节
 
上一个 下一个