[英]Qt zombies: Calling functions containing new with QTimer
我正在尝试使用刷新率为 1s 的QTimer
显示一个动态更新的表。 我正在调用 function create_table
,它又调用create_title
。 代码运行没有任何抱怨,但跟踪 memory 的使用情况,发现它一直在稳步上升,直到程序变得无响应或崩溃。
void MainWindow::TableDisplay(QWidget *tab) {
auto timer = new QTimer(this);
connect(timer, &QTimer::timeout, [refreshed_table_data, tab, this]() {
auto tableView = create_table(tab, refreshed_table_data, "My table");
});
timer->start(1000);
}
罪魁祸首似乎是各种new
语句(由我的代码中的注释指示),每次QTimer
运行循环时,它们似乎都会产生新的僵尸/泄漏。
auto create_title(const std::string &title, QWidget * widget) {
auto tableTitle = new QLabel(title.c_str(), widget); // <-- new
tableTitle->setAlignment(Qt::AlignLeft);
tableTitle->show();
}
auto create_table(QWidget * tab,
const std::vector<std::string> &v,
const std::string &title) {
auto tableView = new QTableView(tab); // <-- new
auto model = new MyModel(v, tab); // <-- new
tableView->setModel(model);
tableView->setStyle(new QProxyStyle(QStyleFactory::create("Fusion"))); // <-- new
tableView->setHorizontalHeader(new QHeaderView(Qt::Horizontal)); // <-- new
create_title(title, tab);
tableView->show();
return tableView;
}
一种解决方案可能是将指针由new
初始化为MainWindow
的成员变量,以便它们只定义一次。 但是,如果我要调用几个这样的定时函数,它很快就会变得很麻烦,更何况考虑到有渲染元素,比如new QProxyStyle(QStyleFactory::create("Fusion"))
等需要的行被赋予成员变量的地位。
我尝试用QScopePointer
包装new
语句,但不幸的是,在create_table
退出其 scope 后,实例立即被破坏,导致表格图形无法呈现。
在不创建僵尸的情况下编写create_table
的正确方法是什么?
对于问题本身:您的createTable
方法可以调用QTimer::singleShot
在一秒钟后安排更新。
auto create_table(QWidget * tab,
const std::vector<std::string> &v,
const std::string &title) {
...
QTimer::singleShot(1000 /*ms*/, this /*context*/, [this, tab, v, title]() {
create_table(tab, v, title);
});
return tableView;
}
然而,正如 Igor 所指出的,整个方法似乎倒退了。 model 应该自我更新,最好是基于事件的,但如果它必须轮询外部资源,它可能必须自己使用计时器。
为视图设置一个全新的 model 非常昂贵(因为视图必须从头开始创建所有内容)并且可能在 GUI 端产生烦人的副作用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.