在Qt中,我必须等待1秒才能让事件处理,所以我使用
QTime lDieTime= QTime::currentTime().addSecs(1);
while (QTime::currentTime() < lDieTime)
QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
但在此之后,我对对象(this->mListIP.currentItem();
)
如果在processEvents期间没有销毁对象,则此工作正常。但是在这个循环中对象可以被破坏。
如何测试窗口小部件/对象是否仍然存在?
我已经尝试了if(!this->isVisible())
但它崩溃了(读访问冲突),因为它不再存在
我的问题与此question
有关因此,如果我无法检查是否存在,如果对象被销毁,我该如何停止我的功能呢?析构函数中有什么东西?尝试捕捉(但我不喜欢)
注意:该函数每2秒由一个来自QBasicTimer的timerEvent调用
编辑:代码结构:
Class A (Widget)
-constructor start a QBasicTimer of 2 seconds
-timerEvent, called by the QBasicTimer every two seconds
Layout containing Class A can destroy Class A object
在timerevent中,我开始一个操作,等待1秒,然后尝试更新小部件。但如果它被摧毁我就无法更新它
edit2:更多代码
void MaryAnnConnectionWidget::timerEvent( QTimerEvent * /*aEvent*/ )
{
//operation base on a socket and a udp broadcast
...
QTime lDieTime= QTime::currentTime().addSecs(1);
while (QTime::currentTime() < lDieTime)
QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
//Operation to handle answers from the broadcast
...
if(this==nullptr) //Exit if we changed window <= CRASH HERE if widget destroyed
return;
//Handle the answers and displays results
...
}
答案 0 :(得分:3)
您的问题是一种XY问题。您认为您的问题是关于如何跟踪对象的生命周期。一种解决方案是使用QPointer
来做到这一点。另一个是不必显式跟踪它,让框架确保您的代码不再运行在不再存在的对象上。所以解决方案是互补的,但最好首先避免这个问题。下面我将解释如何这样做。
假设您从以下可怕的代码开始。您必须将doBefore()
和doAfter()
分解为独立方法:
void Class::timerEvent(QTimerEvent * ev) {
if (ev->timerId() != m_timer.timerId()) return;
doBefore();
auto endTime = QTime::currentTime().addSecs(1);
while (QTime::currentTime() < endTime)
QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
doAfter(mListIP.currentItem());
}
然后通过对代码执行两次转换,可以轻松解决您的问题。
在Qt中,我必须等待1秒才能让事件处理,所以我使用
不,你没有。您必须在经过一秒钟后运行代码。方法如下:
// Qt 5
void Class::timerEvent(QTimerEvent * ev) {
if (ev->timerId() != m_timer.timerId()) return;
doBefore();
QTimer::singleShot(1000, this, [this]{ doAfter(mListIP.currentItem()); });
}
// Qt 4
void Class::timerEvent(QTimerEvent * ev) {
if (ev->timerId() != m_timer.timerId()) return;
doBefore();
m_currentItem = mListIP.currentItem()
QTimer::singleShot(1000, this, SLOT(doAfterCurrent()));
}
void Class::doAfterCurrent() { // must be a slot
doAfter(m_currentItem);
}
我对对象进行操作(this-&gt; mListIP.currentItem();)
如果在该对象的上下文中运行functor / slot,则如果对象死亡,则不会执行functor / slot。因此:
// Qt 5
void Class::timerEvent(QTimerEvent * ev) {
if (ev->timerId() != m_timer.timerId()) return;
doBefore();
auto item = mListIP.currentItem();
Q_ASSERT(!item || this.findChildren<QObject*>().contains(item));
// vvvv -- note the changed context!
QTimer::singleShot(1000, item, [this,item]{ doAfter(item); });
}
// Qt 4
void Class::timerEvent(QTimerEvent * ev) {
if (ev->timerId() != m_timer.timerId()) return;
doBefore();
m_currentItem = mListIP.currentItem();
Q_ASSERT(!m_currentItem || this.findChildren<QObject*>().contains(m_currentItem));
// vvvvvvvvvvvv -- note the changed context!
QTimer::singleShot(1000, m_curentItem, SLOT(doAfterCurrent()));
}
void Class::doAfterCurrent() { // must be a slot
doAfter(m_currentItem);
}
答案 1 :(得分:1)
如果需要指向QObject的安全指针,请使用QPointer。当对象被销毁时它将变为null。我们不清楚您的代码是如何构建的以及您尝试执行此操作的位置,但您也可以连接到对象&#34;销毁&#34;信号,并将其绑定到中止计时器的插槽,以便它不会尝试引用该对象。