是否Q3ListView未能从Qt后台存储注销或代码是错误的
Does Q3ListView fail to unregister from Qt backing store or the code is wrong?
我有以下用例(实际上没有意义,因为它是从现实生活中的工作示例中最小化的,但我认为它在技术上仍然是正确的):
class Dialog : public QDialog
{
public:
Dialog(QWidget* parent)
: QDialog(parent)
{
new Q3ListView(this); // this will crash
// new QWidget(this); // this won't crash
}
};
当删除Dialog
实例时(如代码片段中的注释所示),程序将崩溃或不崩溃,这取决于添加到Dialog
的内容,但仅当主窗口的标志被修改时。下面是MainWindow
类的代码,它使用Dialog
:
class MainWindow : public QMainWindow
{
public:
// the fact that the widget (dialog) below
// has no chance to show seems irrelevant.
// In the real scenario I have, the widget is shown on
// the screen and is closed by the user.
// I've just put the whole sequence of pieces of code
// that result from signal/slot calls, that in turn
// result from a point&click scenario in our application
// into the following function for brevity.
void go()
{
auto dialog = new Dialog(this);
dialog->show();
dialog->close();
disableAlwaysOnTop();
delete dialog; // or dialog->deleteLater();
}
void disableAlwaysOnTop()
{
setAttribute(Qt::WA_Resized, true);
Qt::WindowFlags flags = windowFlags();
setWindowFlags(flags ^ (Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint));
setVisible(true);
}
};
和main
的实现:
int main(int argc, char** argv)
{
QApplication app(argc, argv);
MainWindow mainWindow;
mainWindow.show();
mainWindow.go();
return app.exec();
}
所有行似乎都是重现崩溃的必要条件。
这是一个bug在Qt,还是我做错了什么?
允许手动删除小部件的子组件,并且它们应该自动从父组件注销,如下面的手册引用所示。在我的实际案例中,小部件被删除以从GUI中消失,并且它适用于其他小部件组合。正如上面的评论所指出的,将delete dialog;
更改为dialog->deleteLater();
没有帮助。
似乎有一个问题,在删除Q3ListView
实例从Qt的后台存储,这是堆栈跟踪:
QtGuid4.dll !QWidgetBackingStore::staticContents(QWidget * parent, const QRect &第499行c++
QWidgetBackingStore::sync() Line 1200 c++QWidgetPrivate::syncBackingStore() Line 1896 c++
QtGuid4.dll !QWidget::event(QEvent * event) Line 8694 c++
QtGuid4.dll !QMainWindow::event(QEvent * event) Line 1479 c++
QtGuid4.dll !QApplicationPrivate::notify_helper(QObject * receiver, QEvent * e) Line 4565 c++
QtGuid4.dll !QApplication::notify(QObject * receiver, QEvent * e) Line 4530 c++
QtCored4.dll !QCoreApplication::notifyInternal(QObject * receiver, QEvent * event) Line 955 c++
QtCored4.dll !QCoreApplication::sendEvent(QObject * receiver, QEvent * event) Line 231 c++
QtCored4.dll !QCoreApplicationPrivate::sendPostedEvents(QObject * receiver, int event_type, QThreadData * data) Line 1579 c++
QtCored4.dll !qt_internal_proc(HWND__ * hwnd, unsigned int message, unsigned __int64 wp, __int64 lp) Line 498 c++
(外部代码)QtCored4.dll !QEventDispatcherWin32:: procesvents (QFlags flags) Line 823 c++
QtGuid4.dll !QGuiEventDispatcherWin32::processEvents(QFlags flags) Line 1216 c++
QtCored4.dll !QEventLoop:: procesvents (QFlags flags) Line 150 c++
QtCored4.dll !QEventLoop::exec(QFlags flags) Line 204 c++
QCoreApplication::exec() Line 1227 c++qtguide .dll!QApplication::exec() Line 3824 c++
qt_bug.exe !main(int argc, char * * argv) c++
Qt的一段代码试图在堆栈跟踪中指示的行中使用指向已删除对象的指针:
for (int i = 0; i < count; ++i) {
QWidget *w = staticWidgets.at(i);
QWidgetPrivate *wd = w->d_func();
if (!wd->isOpaque || !wd->extra || wd->extra->staticContentsSize.isEmpty() // ****
|| !w->isVisible() || (parent && !parent->isAncestorOf(w))) {
continue;
}
(wd
指向注释标记行处已删除的对象)。
免责声明:我知道存在更优雅的解决方案,但这是遗留代码,根据Qt的手册:
你也可以自己删除子对象,它们将自己从父对象中移除。
这个代码是有效的。
我们已经在Windows 7 (MSVC 2010 SP1, CL 16), Windows 8 (MSVC 2013 U4, CL 18)和Fedora 20 (GCC 4.8.3)上重现了这个问题。
我已经提交了一个bug报告。由于它涉及到库的旧版本,因此不希望修复它。
无论如何,我们正在陆续删除Qt3Support,所以每个人都被建议;)
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 代码在main()中运行,但在函数中出现错误
- 在VS代码中交叉编译Windows与Linux上的MinGW的SDL程序
- 编译包含字符串的代码时遇到问题
- 我在c++代码中生成了一个运行时#3异常
- 如何在linux终端中同时编译和运行c++代码
- 为cl.exe(Visual Studio代码)指定命令行C++版本
- 在Linux for Windows上编译C++代码时出错
- 我的字符计数代码计算错误.为什么
- 孤立代码块在结构中引发异常
- 在编译C++代码(具有dlib和opencv)到WASM时面临问题
- 为什么我的C#代码在调用回C++COM直到Task时会暂停.等待/线程.加入
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- 此代码是否违反一个定义规则
- 为什么我的代码在输出中增加了93天
- 我的简单if-else语句是如何无法访问的代码
- 使用动态分配的数组会导致代码分析发出虚假的C6386缓冲区溢出警告
- 为什么在这个代码结束循环中没有得到结束
- 在c代码之间共享数据的最佳方式
- 是否Q3ListView未能从Qt后台存储注销或代码是错误的