我正在试图找出为什么我的应用程序崩溃了一整天。一张价值数千字的图片,所以看看这段代码。部首:
class SandboxedAppStat : public QObject
{
Q_OBJECT
private slots:
void pidsTimerTimeout();
public:
QTimer m_PidsTimer;
SandboxedAppStat(QObject *parent = NULL);
};
class SandboxedApp : public QObject
{
Q_OBJECT
private:
static SandboxedAppStat SandboxedAppStat1;
};
实现:
void SandboxedAppStat::pidsTimerTimeout()
{
qDebug() << "whatever";
}
SandboxedAppStat::SandboxedAppStat(QObject *parent)
: QObject(parent)
{
bool b = QObject::connect(&m_PidsTimer, SIGNAL(timeout()),
this, SLOT(pidsTimerTimeout()));
m_PidsTimer.start(500);
}
SandboxedAppStat SandboxedApp::SandboxedAppStat1;
实际上我正在尝试做的是模拟C ++中的静态构造函数行为。我想要
QObject::connect(&m_PidsTimer, SIGNAL(timeout()),
this, SLOT(pidsTimerTimeout()));
m_PidsTimer.start(500);
静态成员SandboxedAppStat1初始化后立即调用。这就是上面显示的代码在SandboxedAppStat的构造函数中的原因。
然而,我的问题是,当我运行该程序时,它会在到达connect(&m_PidsTimer, SIGNAL(timeout()), this, SLOT(pidsTimerTimeout()));
行时崩溃
错误代码c0000005(我猜是访问冲突)。 这是屏幕截图http://dl.dropbox.com/u/3055964/Untitled.gif
如果我将SandboxedAppStat声明为非静态变量,则不会出现崩溃且没有错误。一切正常。
首先我认为崩溃的原因可能是,静态成员的初始化太早,无法调用QObject :: connect,这就是我使用以下代码更新SandboxedAppStat构造函数的原因:
auto *t = this;
QtConcurrent::run([&] () {
Sleep(3000);
bool b = QObject::connect(&(t->m_PidsTimer),
SIGNAL(timeout()), t, SLOT(pidsTimerTimeout()));
t->m_PidsTimer.start(500);
});
正如您所看到的,QObject :: connect在静态SanboxedAppStat初始化3秒后执行,但这也没有帮助,程序在3秒后崩溃。
我真的很困惑,我不明白这个问题的原因是什么。我们不能在静态对象实例中使用信号/槽吗?
我正在使用Qt 4.8.0和MSVC 2010.谢谢
更新
这是一个简单的项目,只包含一个标题和一个源文件(如HostileFork建议的那样)来重现崩溃。 http://dl.dropbox.com/u/3055964/untitled1.zip
答案 0 :(得分:0)
您是否正在寻找定期拨打pidsTimerTimeout
插槽或在施工期间只拨打一次?
如果您希望在课程构建完成后收到信号,请尝试使用QTimer::singleShot
或QMetaObject::invokeMethod
,如果您不需要连续超时。与所有信号一样,只有在处理了窗口系统的事件队列后才会对单个镜头执行操作,这可能会对插槽的执行造成一点延迟。
MyClass::MyClass()
{
// Using a zero singles shot.
QTimer::singleShot( 0, this, SLOT( initialized() ) );
// or using invoke method.
QMetaObject::invokeMethod( this, "initialized", Qt::QueuedConnection );
}
我们确信我们在办公室使用此代码,并且我们在静态对象方面取得了成功。