QT 5.6.1应用程序仅在x86 arch退出插槽后崩溃,但不是x64

时间:2016-06-28 13:52:57

标签: c++ windows qt x86

我面临一个我无法理解的问题,我需要你的灯。我还没有找到关于其他主题的问题的答案。

上下文:

  • 我在Windows 10 x64上使用动态编译的QT 5.6.1(x86和x64)。

问题:

我已经编译了两次基本程序(x86和x64),它只显示一个带按钮的Window,并将按钮连接到“clicked”信号。我的窗口正确显示,但是当我按下我的按钮发出信号时,应用程序在退出连接到SIGNAL的SLOT后立即崩溃(从插槽中正确调用了qDebug)。但我只是面对x86 QT dll的问题......

以下是代码:

的.cpp:

MyWidget::MyWidget()
{
    QMainWindow *pqMainWindow= new QMainWindow(this);
    QPushButton *pqButton= new QPushButton("MyButton");
    /* Setting up the window */
    pqMainWindow->setWindowModality(Qt::WindowModal);
    pqMainWindow->setGeometry(geometry());
    pqMainWindow->move(QPoint(100, 100));
    /* Connecting signal clicked to slot */
    QObject::connect(pqButton, SIGNAL(clicked(bool)), this, SLOT(_onMyActionTriggered(bool)));    
    pqMainWindow->setCentralWidget(pqButton);
    /* Showing the window */
    pqMainWindow->show();
}
MyWidget::~MyWidget()
{
    /* Nothing to do yet */
}
void MyWidget::_onMyActionTriggered(bool bValue)
{
    qDebug("Slot <_onMyActionTriggered> called");
}
int __cdecl main(int argc, char **argv)
{
    QApplication qapp(argc, argv);
    MyWidget widget;
    return qapp.exec();
}

·H

class MyWidget: public QWidget
{
    Q_OBJECT;
    public:
        MyWidget();
        virtual ~MyWidget();
    private slots:
        void _onMyActionTriggered(bool bValue);
    private:
};

这是呼叫追踪:

Qt5Widgets!QAction::activate+0x103
Qt5Widgets!QToolButton::nextCheckState+0x1a
Qt5Widgets!QAbstractButton::click+0x103
Qt5Widgets!QAbstractButton::mouseReleaseEvent+0x7e
Qt5Widgets!QToolButton::mouseReleaseEvent+0xd
Qt5Widgets!QWidget::event+0xa8
Qt5Widgets!QSizePolicy::QSizePolicy+0x83b
Qt5Core!QCoreApplication::translate+0x30f56
Qt5Gui!QGuiApplicationPrivate::processMouseEvent+0x6c1
USER32!SetManipulationInputTarget+0x53
USER32!DispatchMessageW+0x251
USER32!DispatchMessageW+0x10
qwindows!qt_plugin_query_metadata+0x2065
Qt5Core!QCoreApplication::exec+0x160
qt_auth_test!wmain+0x7c
qt_auth_test!QObject::event+0xb5
KERNEL32!BaseThreadInitThunk+0x24
ntdll!RtlUnicodeStringToInteger+0x21e
ntdll!RtlCaptureContext+0xe1

我自己编译过QT,但在使用QT网站上下载的dll和lib时,我的结果相同。

2 个答案:

答案 0 :(得分:1)

感谢大家的帮助,我终于找到了问题。

以下是答案:

我的程序使用stdcall(/ Gz)约定,但QT使用cdecl(/ Gd)。生成的moc文件是使用stdcall约定编译的,这就是导致问题的原因(由于callee和调用者之间的约定不同而在释放参数时出现堆栈问题)。 现在我的程序是使用stdcall约定编译的(因为它对我来说是强制性的)但是生成的moc文件是用cdecl编译的,我在我的私有插槽头上设置了__cdecl关键字!现在它完美无缺!

再次感谢您的时间。我希望有一天这个话题可以帮助某人解决类似问题。

答案 1 :(得分:0)

在隐藏小部件的子级上设置窗口模态毫无意义。也许那是一个问题。请尝试以下操作,并检查是否/何时崩溃。 OS X上肯定存在Qt 5.6错误:当按钮的模态被还原时,小部件仍然没有收到输入,你必须通过其他方式退出应用程序。

#include <QtWidgets>

int main(int argc, char **argv)
{
   int n = 0;
   QApplication app{argc, argv};
   QPushButton widget{"Widget"};
   QPushButton button{"Button", &widget};
   button.setWindowFlags(Qt::Window);

   QObject::connect(&button, &QPushButton::clicked, [&]{
      button.setText(button.text().append("."));
      ++n;
      if (n == 5) {
         button.setWindowModality(Qt::WindowModal);
         button.hide();
         button.show();
      }
      else if (n == 10) {
         button.setWindowModality(Qt::NonModal);
         button.hide();
         button.show();
      }
      else if (n == 15)
         app.quit();
   });

   button.move(widget.geometry().bottomRight());
   widget.show();
   button.show();
   return app.exec();
}