- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我制作了一个基于 QGraphicsView
的小部件 (QDataflowCanvas),我将信号 QGraphicsScene::selectionChanged()
连接到插槽 MainWindow::onSelectionChanged
我的主窗口:
void MainWindow::onSelectionChanged()
{
// canvas is ptr to QDataflowCanvas, subclass of QGraphicsView
auto selNodes = canvas->selectedNodes();
auto selConns = canvas->selectedConnections();
...
}
问题发生在我关闭 MainWindow
并且在 QGraphicsView
中选择了一些项目时。
我认为我不需要提供完整的代码(尽管可以找到 here ),因为我已经隔离了崩溃的原因。
这是将要发生的事情(按因果顺序):
clear()
)从崩溃的堆栈跟踪中可以更详细地看到:
我找到了这个解决方法:如果我断开 MainWindow::~MainWindow
中的信号,它当然不会崩溃:
MainWindow::~MainWindow()
{
QObject::disconnect(canvas->scene(), &QGraphicsScene::selectionChanged, this, &MainWindow::onSelectionChanged);
}
但这似乎是一种非常不典型的做法:我从来没有发现自己必须手动严格的信号槽连接,否则程序会崩溃。
必须有更合适的解决方案。
最佳答案
首先,你的项目名称是错误的。采用 Q
前缀的命名空间。在任何使用 Qt 的项目中,您都不应该有任何以 Q
为前缀的类。例如,您应该将项目重命名为 DataflowCanvas
。
三种解决方案:
按值保存所有子项,根据它们的依赖项对子项进行排序。从 QDataFlowCanvas
调用的 QWidgetPrivate::deleteChildren
将是空操作,或者至少不会触及您关心的对象。
连接到 MainWindow::onSelectionChanged
插槽时使用旧的 connect
语法。请注意,当您的插槽被调用时,主窗口对象是 QWidget
动态类型,而不是 MainWindow
类型。使用旧连接语法建立的连接尊重对象的动态类型,并且与给定类的插槽建立的连接将保证该对象动态地属于该类,即在运行时。
在析构函数中清除选择 - 然后将不会处理任何进一步的选择更改。
第一个解决方案使一切都变得明确,这就是我要使用的解决方案:
class DataFlowCanvas : public QGraphicsView {
...
private:
QDataflowModel *model_;
QDataflowTextCompletion *completion_;
QSet<QDataflowNode*> ownedNodes_;
QSet<QDataflowConnection*> ownedConnections_;
QMap<QDataflowModelNode*, QDataflowNode*> nodes_;
QMap<QDataflowModelConnection*, QDataflowConnection*> connections_;
bool showIOletsTooltips_;
bool showObjectHoverFeedback_;
bool showConnectionHoverFeedback_;
qreal gridSize_;
bool drawGrid_;
QGraphicsSecene scene_;
};
场景在任何其他字段之前被破坏。问题解决了。你也应该按值(value)持有其他一切。例如。 completion_
等。指针间接寻址没有用。
第二个解决方案突出了一个不幸的 Qt 错误。也就是说,在下面的代码中,旧的连接语法永远不会调用 Derived2::aSlot2
,因为在调用插槽时,对象不属于 Derived2
再输入:
#include <QtCore>
int ctr1, ctr2;
struct Derived1 : QObject {
Q_SLOT void aSlot1() { ctr1++; qDebug() << __FUNCTION__; }
Q_SIGNAL void aSignal();
~Derived1() { Q_EMIT aSignal(); }
Q_OBJECT
};
struct Derived2 : Derived1 {
Q_SLOT void aSlot2() { ctr2++; qDebug() << __FUNCTION__ << qobject_cast<Derived2*>(this); }
Q_OBJECT
};
int main() {
{
Derived2 d;
QObject::connect(&d, &Derived2::aSignal, &d, &Derived2::aSlot2);
QObject::connect(&d, SIGNAL(aSignal()), &d, SLOT(aSlot2()));
QObject::connect(&d, SIGNAL(aSignal()), &d, SLOT(aSlot1()));
}
Q_ASSERT(ctr1 == 1);
Q_ASSERT(ctr2 == 1);
}
#include "main.moc"
输出清楚地说明了问题:
aSlot2 QObject(0x0) <-- aSlot2 called but `this` is of `Derived1*` type!
aSlot1
关于c++ - Qt widget析构函数通过connected signal间接调用widget方法,崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50318413/
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引起辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the he
我正在试验 jquery-ui 并查看和克隆一些示例。在一个示例(自动完成的组合框)中,我看到一个带有 ui-widget 类的 anchor (a) 元素,它与包含的 css 文件中的 .ui-wi
在我帮助维护的代码中,我发现了多个如下所示的代码示例: Description := IfThen(Assigned(Widget), Widget.Description, 'No Widget')
这个问题在这里已经有了答案: CSS Performance Question (8 个答案) 关闭 9 年前。 这是一个很常见的情况。假设我们有一些标记: 我们可以使用 2 个选项来
这个问题在这里已经有了答案: CSS: Class name selector- name starts with (2 个答案) 关闭 5 年前。
我有一个布局,其中Row小部件中有两个子部件,这两个都是灵活的小部件。左侧的小部件包含红色和蓝色的小部件,我希望根据右侧小部件的高度增加蓝色小部件的高度(这是一个灵活的小部件,其FLEX值为7)。。例
我有一个布局,其中Row小部件中有两个子部件,这两个都是灵活的小部件。左侧的小部件包含红色和蓝色的小部件,我希望根据右侧小部件的高度增加蓝色小部件的高度(这是一个灵活的小部件,其FLEX值为7)。。例
这是一个代码: import 'package:flutter/material.dart'; import 'package:flutterapp/ui/pages/notes_home.dart'
ListView、GridView、SingleChildScrollView 等小部件是可滚动的小部件,而Container、SizedBox, Column 不是。 有没有办法检查 Widget
假设我在 Python 中有这个简单的函数: def f(gender, name): if gender == 'male': return ranking_male(nam
我不想听起来像个糟糕的新手,但是小部件是独立的应用程序吗?例如,我正在为 Android 创建一个新闻阅读器应用程序,我想要一个主屏幕小部件。我是将小部件创建为 Hook 到其他应用程序的单独项目/应
如何告诉 Tk 小部件告诉我它的子级是什么(或谁,视情况而定)?有这个命令吗? 例如,给定一个带有标签、按钮和其他装饰的 Canvas 小部件 .cvs ...如何查询 Canvas ? 最佳答案 w
我为 Android 开发了一个 APP + 主屏幕小部件。现在我更新了应用程序(增加了版本代码/名称)但是当我安装时,它不会自动替换屏幕上现有的小部件。它只是说“问题加载小部件”。 有什么想法吗??
我是小部件开发的新手..我设法构建了一个无法调整大小的小部件..我希望它像 - 用户设法根据自己调整大小......有人可以告诉我如何制作它可能吗? 谢谢 friend 。 最佳答案 AppWidge
我有一个小部件列表: List widgetList = List(); widgetList.add(WidgetA()); widgetList.add(WidgetB()); widgetLis
对不起,我的英语不好! 我开发了一个今日小部件。我需要从小部件启动 map 应用程序(例如),并且在设备锁定时不工作。在这种情况下如何检测锁定的设备并启动解锁屏幕? 问候, 最佳答案 而不是使用 UI
我正在尝试制作我的小部件的免费版本,我想向小部件添加广告,这可能吗?如果是这样怎么办? 最佳答案 小部件应用程序中的 View 仅限于: 模拟时钟 按钮 天文台 图像按钮 ImageView 进度条
我在 Android Studio 中创建了一个新项目,然后添加了一个新的小部件并在我的 Nexus 5 5.1 上运行该应用程序,它可以工作,但是当尝试将小部件添加到主屏幕时,它没有出现在小部件列表
我有一个字符串 'currentMessage' 和一个用于显示它的标签。我有一个 Toplevel 小部件,其中包含一个文本小部件,为“currentMessage”提供新值: from tkint
我尝试使用这个 link 解决我的问题 update - I figured out that there is something wrong with the setter of the pend
我是一名优秀的程序员,十分优秀!