应用新样式时如何更新小部件
How to update widget when new style is applied
我正在使用一个列表进行扩展,该列表包含一个带有文本项 (St.label) 的复选框,在切换时会改变样式。
我正在监听切换事件,当项目被切换时,我在我的 Stlabel 上使用 set_style_class_name() 为我的文本设置了新样式。但是对象的样式不会改变。我找到的唯一解决方案是销毁并重新制作列表中的所有项目,并在对象的初始化中设置不同的 class。
我怎样才能更新已检查的项目?
这里是我正在使用的项目,我在触发 toggle() 函数的复选框上放置了一个侦听器,在这个函数中我正在更新 class,这应该删除 'text-checked' class 所以文本不应该有 'text-decoration:line-through' 属性。
const PopupMenu = imports.ui.popupMenu;
const Lang = imports.lang;
const { Atk, Clutter, St, GObject } = imports.gi;
const ExtensionUtils = imports.misc.extensionUtils;
const Me = ExtensionUtils.getCurrentExtension();
const CheckboxLib = Me.imports.src.checkbox;
var PopupCheckBoxMenuItem = GObject.registerClass({
Signals: {
'toggled': { param_types: [GObject.TYPE_BOOLEAN] },
'deleted': { param_types: [GObject.TYPE_BOOLEAN] }
},
}, class PopupCheckBoxMenuItem extends PopupMenu.PopupBaseMenuItem {
_init(text, active, params) {
super._init(params);
this.label = new St.Label({
text: text,
y_align:Clutter.ActorAlign.CENTER,
x_expand: true,
style_class: active ? "text-checked" : ""
});
this.tags = new St.Label({
text: "API",
y_align:Clutter.ActorAlign.CENTER,
style_class: "tag-item"
});
this.icon = new St.Button({
style_class: 'remove-task',
can_focus: true,
});
this.icon.connect('clicked', Lang.bind(this,function(){
this.emit('deleted', this._checkbox.state);
}));
this.icon.add_actor(new St.Icon({
icon_name: 'window-close-symbolic',
style_class: 'icon-remove-task'
}));
this._checkbox = new CheckboxLib.CheckBox(active);
this._checkbox.connect('clicked', Lang.bind(this,function(){
this.toggle();
}));
this.accessible_role = Atk.Role.CHECK_MENU_ITEM;
this.checkAccessibleState();
this._statusBin = new St.Bin({
x_align: Clutter.ActorAlign.START,
x_expand: false,
});
this.add_child(this._statusBin);
this.label_actor = this.label;
this.add_child(this.tags);
this.add_child(this.label);
this.add_child(this.icon);
this._statusLabel = new St.Label({
text: '',
style_class: 'popup-status-menu-item',
});
this._statusBin.child = this._checkbox;
}
setStatus(text) {
if (text != null) {
this._statusLabel.text = text;
this._statusBin.child = this._statusLabel;
this.reactive = false;
this.accessible_role = Atk.Role.MENU_ITEM;
} else {
this._statusBin.child = this._checkbox;
this.reactive = true;
this.accessible_role = Atk.Role.CHECK_MENU_ITEM;
}
this.checkAccessibleState();
}
activate(event) {
super.activate(event);
}
toggle() {
this._checkbox.toggle();
this.emit('toggled', this._checkbox.state);
//Updating class
this.label.set_style_class_name("new_class");
this.label.real_style_changed();
this.checkAccessibleState();
}
get state() {
return this._checkbox.state;
}
get delete_icon() {
return this.icon;
}
setToggleState(state) {
this._checkbox.state = state;
this.checkAccessibleState();
}
checkAccessibleState() {
switch (this.accessible_role) {
case Atk.Role.CHECK_MENU_ITEM:
if (this._checkbox.state)
this.add_accessible_state(Atk.StateType.CHECKED);
else
this.remove_accessible_state(Atk.StateType.CHECKED);
break;
default:
this.remove_accessible_state(Atk.StateType.CHECKED);
}
}
});
最直接的好像是St.Widget.style_changed()
。这似乎是强制将样式状态标记为脏并触发重绘(St.Label
是一个子类,所以只需调用myLabel.style_changed()
)。
不过,正确的路线可能是 St.Widget.ensure_style()
。
我没有看得太深,但问题可能是小部件没有被标记为样式已更改,或者更改可能没有传播到 children 或其他东西。
问题是 属性 我在 css class 中更改了。
由于未知原因,当我设置仅带有文本装饰 属性 的 class 时,样式更改似乎不会重绘,但如果我添加颜色更改,即使它即使没有 St.Widget.style_changed().
也是一样的颜色
因此,如果我 this.label.set_style_class_name("text-checked"); 来更改我的 class,如果我的 css class 如下:
.text-checked
{
text-decoration: line-through !important;
}
但是这项工作:
.text-checked
{
text-decoration: line-through !important;
color: black;
}
一定是 Gjs 组件的样式更改事件如何工作的问题。
问题在这里打开:https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/2811
我正在使用一个列表进行扩展,该列表包含一个带有文本项 (St.label) 的复选框,在切换时会改变样式。
我正在监听切换事件,当项目被切换时,我在我的 Stlabel 上使用 set_style_class_name() 为我的文本设置了新样式。但是对象的样式不会改变。我找到的唯一解决方案是销毁并重新制作列表中的所有项目,并在对象的初始化中设置不同的 class。
我怎样才能更新已检查的项目?
这里是我正在使用的项目,我在触发 toggle() 函数的复选框上放置了一个侦听器,在这个函数中我正在更新 class,这应该删除 'text-checked' class 所以文本不应该有 'text-decoration:line-through' 属性。
const PopupMenu = imports.ui.popupMenu;
const Lang = imports.lang;
const { Atk, Clutter, St, GObject } = imports.gi;
const ExtensionUtils = imports.misc.extensionUtils;
const Me = ExtensionUtils.getCurrentExtension();
const CheckboxLib = Me.imports.src.checkbox;
var PopupCheckBoxMenuItem = GObject.registerClass({
Signals: {
'toggled': { param_types: [GObject.TYPE_BOOLEAN] },
'deleted': { param_types: [GObject.TYPE_BOOLEAN] }
},
}, class PopupCheckBoxMenuItem extends PopupMenu.PopupBaseMenuItem {
_init(text, active, params) {
super._init(params);
this.label = new St.Label({
text: text,
y_align:Clutter.ActorAlign.CENTER,
x_expand: true,
style_class: active ? "text-checked" : ""
});
this.tags = new St.Label({
text: "API",
y_align:Clutter.ActorAlign.CENTER,
style_class: "tag-item"
});
this.icon = new St.Button({
style_class: 'remove-task',
can_focus: true,
});
this.icon.connect('clicked', Lang.bind(this,function(){
this.emit('deleted', this._checkbox.state);
}));
this.icon.add_actor(new St.Icon({
icon_name: 'window-close-symbolic',
style_class: 'icon-remove-task'
}));
this._checkbox = new CheckboxLib.CheckBox(active);
this._checkbox.connect('clicked', Lang.bind(this,function(){
this.toggle();
}));
this.accessible_role = Atk.Role.CHECK_MENU_ITEM;
this.checkAccessibleState();
this._statusBin = new St.Bin({
x_align: Clutter.ActorAlign.START,
x_expand: false,
});
this.add_child(this._statusBin);
this.label_actor = this.label;
this.add_child(this.tags);
this.add_child(this.label);
this.add_child(this.icon);
this._statusLabel = new St.Label({
text: '',
style_class: 'popup-status-menu-item',
});
this._statusBin.child = this._checkbox;
}
setStatus(text) {
if (text != null) {
this._statusLabel.text = text;
this._statusBin.child = this._statusLabel;
this.reactive = false;
this.accessible_role = Atk.Role.MENU_ITEM;
} else {
this._statusBin.child = this._checkbox;
this.reactive = true;
this.accessible_role = Atk.Role.CHECK_MENU_ITEM;
}
this.checkAccessibleState();
}
activate(event) {
super.activate(event);
}
toggle() {
this._checkbox.toggle();
this.emit('toggled', this._checkbox.state);
//Updating class
this.label.set_style_class_name("new_class");
this.label.real_style_changed();
this.checkAccessibleState();
}
get state() {
return this._checkbox.state;
}
get delete_icon() {
return this.icon;
}
setToggleState(state) {
this._checkbox.state = state;
this.checkAccessibleState();
}
checkAccessibleState() {
switch (this.accessible_role) {
case Atk.Role.CHECK_MENU_ITEM:
if (this._checkbox.state)
this.add_accessible_state(Atk.StateType.CHECKED);
else
this.remove_accessible_state(Atk.StateType.CHECKED);
break;
default:
this.remove_accessible_state(Atk.StateType.CHECKED);
}
}
});
最直接的好像是St.Widget.style_changed()
。这似乎是强制将样式状态标记为脏并触发重绘(St.Label
是一个子类,所以只需调用myLabel.style_changed()
)。
不过,正确的路线可能是 St.Widget.ensure_style()
。
我没有看得太深,但问题可能是小部件没有被标记为样式已更改,或者更改可能没有传播到 children 或其他东西。
问题是 属性 我在 css class 中更改了。
由于未知原因,当我设置仅带有文本装饰 属性 的 class 时,样式更改似乎不会重绘,但如果我添加颜色更改,即使它即使没有 St.Widget.style_changed().
也是一样的颜色因此,如果我 this.label.set_style_class_name("text-checked"); 来更改我的 class,如果我的 css class 如下:
.text-checked
{
text-decoration: line-through !important;
}
但是这项工作:
.text-checked
{
text-decoration: line-through !important;
color: black;
}
一定是 Gjs 组件的样式更改事件如何工作的问题。
问题在这里打开:https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/2811