QLineEdit setText函数导致程序crash的问题解决

14 篇文章 0 订阅

很早在程序代码中有个bug,不明原因的崩溃,分析是程序中的指针引起的,查找了很长的时间,没找到,问题依旧。基于此问题出现的频率很低,就此搁浅。 今天偶然在仿真程序是复现了此问题,还定位了调用堆栈,经过一番努力终于解决此大bug。
程序崩的堆栈调用图
问题:
我的问题与这个基本描述基本相同,参考链接如下:
Fast changing QLineEdit crashing the application
https://stackoverflow.com/questions/3571046/fast-changing-qlineedit-crashing-the-application
原因是:
It looks to me like you call setText() from the non-UI thread. That won’t work, QWidgets are not thread-safe
在非GUI线程中调用QWidget方法(非线程安全),程序崩溃。
--------------------------------------------------恍然大悟啊-----------------------------
Qt assistant Threads and QObjects 文中说到:
Although QObject is reentrant, the GUI classes, notably QWidget and all its subclasses, are not reentrant. They can only be used from the main thread. As noted earlier, QCoreApplication::exec() must also be called from that thread.
In practice, the impossibility of using GUI classes in other threads than the main thread can easily be worked around by putting time-consuming operations in a separate worker thread and displaying the results on screen in the main thread when the worker thread is finished. This is the approach used for implementing the Mandelbrot and the Blocking Fortune Client example

原来不能在非GUi线程中调用QWidgets 的方法,于是寻找解决方法,这个大牛给出了解决方案:
If you are calling setText from other than main thread (UI-thread), you just need to move that operation to the main thread. Add a slot function to your mainwindow (where your labels are) and send a signal *with acceleration values as parameters * from your other thread.
也就是说:在非GUI线程中发送信号,在Gui线程中调用QWidget方法即可。
后来检索到了这篇文章,文中使用了QThread实现非GUI线程与GUI线程的通信方法。
在QT中如何实现Thread与GUI的主线程连通
好了,原来使用connect函数,信号和槽的这种机制来解决问题的。那么就来看看这个函数如何实现跨线程通信。
QObject::connect(
const QObject * sender, //发送者
const char * signal, //信号
const QObject * receiver, //接受者
const char * method, //槽函数
Qt::ConnectionType type = Qt::AutoConnection)

这个函数平时都这么用的
connect(this,SIGNAL(upDateTipsStr(const QString &)), m_plabelTips, SLOT(setText(const QString &)));

写成伪代码就是:
if(emit upDateTipsStr(const QString &) )
m_plabelTips->setText();

前四个参数都好理解,第五个参数缺省了。咱们重点看看第五个参数的含义:
Qt::AutoConnection 0 (Default) If the receiver lives in the thread that emits the signal, Qt::DirectConnection is used. Otherwise, Qt::QueuedConnection is used. The connection type is determined when the signal is emitted.
默认值,当发送者与接收者处于同一线程中时,使用 Qt::DirectConnection,否则使用Qt::QueuedConnection。

Qt::DirectConnection 1 The slot is invoked immediately when the signal is emitted. The slot is executed in the signalling thread.
槽函数在信号发送的线程中立刻执行

Qt::QueuedConnection 2 The slot is invoked when control returns to the event loop of the receiver’s thread. The slot is executed in the receiver’s thread.
当接收线程接管程序后,槽函数在信号接受的线程中执行

Qt::BlockingQueuedConnection 3 Same as Qt::QueuedConnection, except that the signalling thread blocks until the slot returns. This connection must not be used if the receiver lives in the signalling thread, or else the application will deadlock.
与Qt::QueuedConnection差不多,除了发信号的线程将阻塞直到槽函数执行完毕后,才解除阻塞。注意:当发送信号与槽处于同一线程中时,将出现死锁。

Qt::UniqueConnection 0x80 This is a flag that can be combined with any one of the above connection types, using a bitwise OR. When Qt::UniqueConnection is set, QObject::connect() will fail if the connection already exists (i.e. if the same signal is already connected to the same slot for the same pair of objects). This flag was introduced in Qt 4.6.
可与上述的flag进行OR操作,当相同的信号连接了形同的槽函数时,该connect将返回false。
总结:也就是说当跨线程使用connect时,默认使用的类型Qt::QueuedConnection。
至此,此问题算是告一段落。
如果您还有什么好的解决方法欢迎留言。


2018年12月13日 19:46:03
南京

追求进步
永不止步

  • 8
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: A:QLineEdit 的槽函数是用来响应 QLineEdit 控件的信号的函数,可以在其中编写相应的逻辑代码。常见的槽函数有 textChanged()、returnPressed()、editingFinished() 等。 ### 回答2: QLineEdit是Qt中的一个控件,槽函数是Qt中用于响应信号的一种机制。 在使用QLineEdit时,我们常常需要对用户输入的数据进行处理或者进行一些特定的操作。这时就可以通过定义一个槽函数来实现。 槽函数是一个普通的成员函数,需要在类中进行定义,并且需要在槽函数前面加上slots关键字进行声明。槽函数可以有参数,也可以没有参数。 当用户输入完成后,QLineEdit控件会触发一个信号,我们只需要将这个信号和对应的槽函数进行连接,就可以实现在用户输入完成后对输入数据进行处理的功能了。 例如,我们可以定义一个槽函数来实现对用户输入的内容进行判断和处理。在该槽函数中,我们可以获取用户输入的文本,然后进行相应的操作,比如判断输入是否符合要求并作出相应的提示。 另外,我们还可以在槽函数中修改QLineEdit的属性,比如设置文本框的颜色、大小等等,以达到一些特定的效果。 总之,QLineEdit的槽函数提供了一种机制,使得我们可以方便地对用户输入的内容进行处理和操作,从而更好地满足应用程序的需求。 ### 回答3: QLineEdit是Qt框架中的一个控件,用于用户输入单行文本。在Qt中,槽函数是用来响应特定信号的函数。对于QLineEdit来说,常用的槽函数是textChanged()和returnPressed()。 textChanged()槽函数会在QLineEdit中的文本内容发生变化时被调用。它可以用来实时监测用户的输入,并作出相应的处理。例如,我们可以用这个槽函数来实现文本输入的自动补全功能,或者用来验证用户输入的有效性。在槽函数中,我们可以通过调用QLineEdit的text()函数来获取当前输入的文本内容。 returnPressed()槽函数会在用户在QLineEdit中按下回车键时被调用。这个槽函数常用于实现文本的提交操作。例如,当用户在QLineEdit中输入完数据后按下回车键,我们可以在returnPressed()槽函数中调用相应的函数来处理用户输入的数据。 除了这两个常用的槽函数外,我们还可以根据实际需求自定义其他的槽函数。我们可以通过使用Qt的信号与槽机制,将其他组件的信号与QLineEdit的槽函数相连接,实现更复杂的功能。例如,我们可以将QComboBox的currentTextChanged()信号与QLineEditsetText()槽函数相连接,从而在选择不同的选项时自动更新QLineEdit的内容。 总结来说,QLineEdit的槽函数能够对用户的输入进行实时监测和处理,并可以响应用户的操作,例如回车键的按下。这样,我们可以通过槽函数来实现一些实用的功能,提升用户体验。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值