我正在嘗試使用QTimer1s 的重繪 率顯示一個動態更新的表。我正在呼叫該函式create_table,該函式又呼叫create_title. 代碼運行時沒有任何抱怨,但跟蹤記憶體使用情況會發現它一直在穩步上升,直到程式變得無回應或崩潰。
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"))等)時,需要賦予成員變數的狀態。
我嘗試new用 s 包裝陳述句,QScopePointer但不幸的是,實體在create_table超出其范圍后立即被破壞,導致表格圖形無法呈現。
create_table在不創建僵尸的情況下,正確的寫作方式是什么?
uj5u.com熱心網友回復:
對于問題本身:您的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 所指出的,整個方法似乎倒退了。模型應該自我更新,最好是基于事件的,但如果它必須輪詢外部資源,它可能必須自己使用計時器。
為視圖設定一個全新的模型非常昂貴(因為視圖必須從頭開始創建所有內容)并且可能在 GUI 端產生煩人的副作用。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/509852.html
標籤:C qtqt6
