在下面的 gtk4 代碼中,我試圖EditableLabel通過洗掉 cooresponding 來從顯示中洗掉一個StringObject. connect_editing_notify這應該在回呼指定的編輯完成后發生。
如果我使用回傳鍵運行程式并退出編輯模式,那么它會按預期作業:標簽消失。但是,如果我通過選擇不同的標簽退出編輯模式,那么我會得到一個重復的控制臺列印,說明斷言失敗:
(viewdb:13773): Gtk-CRITICAL **: 17:35:26.754: gtk_widget_get_parent: assertion 'GTK_IS_WIDGET (widget)' failed
(viewdb:13773): Gtk-CRITICAL **: 17:35:26.754: gtk_widget_get_parent: assertion 'GTK_IS_WIDGET (widget)' failed
(viewdb:13773): Gtk-CRITICAL **: 17:35:26.754: gtk_widget_get_parent: assertion 'GTK_IS_WIDGET (widget)' failed
編輯后如何干凈地洗掉 EditableLabel ?
use gtk::glib::clone;
use gtk::prelude::*;
use gtk::{
Application, ApplicationWindow, EditableLabel, ListView, SignalListItemFactory,
SingleSelection, StringList, StringObject, Widget,
};
fn build_ui(app: &Application) {
let model: StringList = vec!["One", "Two", "Three", "Four"].into_iter().collect();
let selection_model = SingleSelection::new(Some(&model));
let factory = SignalListItemFactory::new();
factory.connect_setup(move |_, listitem| {
let label = EditableLabel::builder().build();
listitem.set_child(Some(&label));
listitem
.property_expression("item")
.chain_property::<StringObject>("string")
.bind(&label, "text", Widget::NONE);
label.connect_editing_notify(
clone!( @strong model, @strong listitem => move |lbl: &EditableLabel| {
if !lbl.is_editing() {
let position = listitem.position();
model.remove(position); // remove model entry cooresponding to edit.
}
}),
);
});
let view = ListView::new(Some(&selection_model), Some(&factory));
let window = ApplicationWindow::builder()
.application(app)
.child(&view)
.build();
window.present();
}
fn main() {
let app = Application::builder().build();
app.connect_activate(build_ui);
app.run();
}
uj5u.com熱心網友回復:
在專案仍在處理某些事件時從其父專案中移除專案有時會導致問題。
簡單的解決方法是在延遲函式中進行洗掉。在 C 中,g_idle_add()正確使用會很麻煩。但在 Rust 中,這非常簡單:
gtk::glib::source::idle_add_local_once(
clone!(@strong model =>
move || model.remove(position)
)
);
但請注意,由于idle函式在未來某個未指定的時間運行,因此(盡管可能性很小position)回呼運行時(串列中的普通索引)的值可能會參考不同的專案。
我沒有測驗它,但我認為將listitem自身保留在回呼中更明智:
gtk::glib::source::idle_add_local_once(
clone!(@strong model, @weak listitem =>
move || {
let position = listitem.position();
if position != INVALID_LIST_POSITION {
model.remove(position)
}
}
)
);
弱克隆將確保僅在專案仍然存在時才呼叫它。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/482575.html
上一篇:在活動AndroidStudioJava上顯示文本和json
下一篇:多行按鈕-Flutter
