Update/refresh Gtk3 中的小部件 (pygobject) 和 python3
Update/refresh Widget in Gtk3 (pygobject) and python3
我希望按钮的颜色在我点击时改变。
或者更笼统地说,我想 update/refresh Gtk.Button 或 Gtk.Box。整个 Gtk.Window 也可以。
我发现在 Gtk3 中更新小部件的唯一方法是 Gtk.widget.queue_draw() 方法,但它看起来像
仅适用于 Gtk.DrawingArea(Drawin with cairo on Zetcode,它适用于 Gtk2,但我在那里读过
本节未做太多改动)。我假设它适用于任何小部件,因为它被命名为
gtk.widget.queue_draw 而不是 gtk.drawingArea.queue_draw 而且它也没有产生
错误,但它似乎被省略了。
我可能对它应该如何工作有错误的理解。我之前制作的唯一 guis 是
前段时间在 Java 中是简单的事情。
所以这是我的代码示例:
# -*- coding: utf-8 -*-
from gi.repository import Gtk, Gdk
import cairo
a = 0
class ProgWindow(Gtk.Window):
def __init__(self):
super(ProgWindow, self).__init__() # don't know what this is doing, works also without
self.window = Gtk.Window.__init__(self, title="example")
self.connect("delete-event", Gtk.main_quit)
box = Gtk.Box()
self.add(box)
button = Gtk.Button("Hello")
if (a==0):
button.set_name('green_button')
button.set_tooltip_text("should be green")
else:
button.set_name('red_button')
button.set_tooltip_text("should be red")
button.connect("clicked", callback_clicked)
box.add(button)
def callback_clicked(self):
global a
print(a)
a = 1
self.queue_draw()
gui() # creates a new window with the correct colour and tool tip
def gui():
win = ProgWindow()
win.show_all()
Gtk.main()
style_provider = Gtk.CssProvider()
css_data = """
#green_button{
background: #009900;
font-size: 120%;
font-weight: 600;
}
#red_button{
background: #FF0000;
font-size: 120%;
font-weight: 600;
}
"""
style_provider.load_from_data(css_data.encode())
Gtk.StyleContext.add_provider_for_screen(
Gdk.Screen.get_default(),
style_provider,
Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION
)
if __name__ == "__main__":
gui()
我也在某处读到,有可能使一个区域无效。那可能是这样做的方法吗?
我还读到,一旦再次到达 Gtk.main() 循环,事情就会更新。
如果是这样,我该如何唤起这一点?正如我所说,我是 gui 编程的新手,但我的理解是,
这就是它 "stuck" 大部分时间等待用户输入的地方。
或者删除小部件并在同一个 space 中放置一个新的小部件可以完成这项工作吗?
任何帮助和解释将不胜感激
谢谢
您不需要为此 运行 queue_draw()
。您也不应该在每次希望按钮更改颜色时都重新创建 GUI。这可能会把事情搞砸,因为在 gui()
中你创建了一个新的 window 并用 Gtk.main()
开始了一个新的主循环,导致许多主循环 运行 递归。这是你不想要的。
而是使用 button.set_name('green-button')
或 red-button
来更改颜色。除了从信号处理程序返回之外,不需要采取进一步的行动。
更好的方法是使用样式 类 而不是 ID — 您可能希望有多个绿色或红色按钮。在这种情况下,将 .green-button
和 .red-button
放入 CSS(而不是 #green-button
和 #red-button
)并使用它来更改颜色:
button.get_style_context().remove_class('green-button')
button.get_style_context().add_class('red-button')
反之亦然。
你把它弄得太复杂了,下面是一个简化版本,点击时按钮会变成绿色。
p.s。
像这样更改小部件的颜色应该是一个例外而不是规则,破坏用户主题通常不是一个好主意。
from gi.repository import Gtk
class CSSButtonApp(object):
def __init__(self):
self.mycolor = '''
GtkButton {
border-image: none;
background-image: none;
background-color: green;
color: white;
}
'''
self.window = Gtk.Window()
self.window.set_title('CSS Button')
self.window.set_default_size(200, 100)
self.window.set_border_width(10)
self.window.connect('destroy', lambda w: Gtk.main_quit())
button = Gtk.Button(label="My Button")
self.window.add(button)
provider = Gtk.CssProvider()
provider.load_from_data(self.mycolor)
button.connect("clicked", self.apply_css, provider)
self.window.show_all()
def apply_css(self, widget, provider):
Gtk.StyleContext.add_provider(widget.get_style_context(),
provider,
Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)
def main(self):
Gtk.main()
if __name__ == '__main__':
app = CSSButtonApp()
app.main()
我希望按钮的颜色在我点击时改变。
或者更笼统地说,我想 update/refresh Gtk.Button 或 Gtk.Box。整个 Gtk.Window 也可以。
我发现在 Gtk3 中更新小部件的唯一方法是 Gtk.widget.queue_draw() 方法,但它看起来像
仅适用于 Gtk.DrawingArea(Drawin with cairo on Zetcode,它适用于 Gtk2,但我在那里读过
本节未做太多改动)。我假设它适用于任何小部件,因为它被命名为
gtk.widget.queue_draw 而不是 gtk.drawingArea.queue_draw 而且它也没有产生
错误,但它似乎被省略了。
我可能对它应该如何工作有错误的理解。我之前制作的唯一 guis 是
前段时间在 Java 中是简单的事情。
所以这是我的代码示例:
# -*- coding: utf-8 -*-
from gi.repository import Gtk, Gdk
import cairo
a = 0
class ProgWindow(Gtk.Window):
def __init__(self):
super(ProgWindow, self).__init__() # don't know what this is doing, works also without
self.window = Gtk.Window.__init__(self, title="example")
self.connect("delete-event", Gtk.main_quit)
box = Gtk.Box()
self.add(box)
button = Gtk.Button("Hello")
if (a==0):
button.set_name('green_button')
button.set_tooltip_text("should be green")
else:
button.set_name('red_button')
button.set_tooltip_text("should be red")
button.connect("clicked", callback_clicked)
box.add(button)
def callback_clicked(self):
global a
print(a)
a = 1
self.queue_draw()
gui() # creates a new window with the correct colour and tool tip
def gui():
win = ProgWindow()
win.show_all()
Gtk.main()
style_provider = Gtk.CssProvider()
css_data = """
#green_button{
background: #009900;
font-size: 120%;
font-weight: 600;
}
#red_button{
background: #FF0000;
font-size: 120%;
font-weight: 600;
}
"""
style_provider.load_from_data(css_data.encode())
Gtk.StyleContext.add_provider_for_screen(
Gdk.Screen.get_default(),
style_provider,
Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION
)
if __name__ == "__main__":
gui()
我也在某处读到,有可能使一个区域无效。那可能是这样做的方法吗?
我还读到,一旦再次到达 Gtk.main() 循环,事情就会更新。
如果是这样,我该如何唤起这一点?正如我所说,我是 gui 编程的新手,但我的理解是,
这就是它 "stuck" 大部分时间等待用户输入的地方。
或者删除小部件并在同一个 space 中放置一个新的小部件可以完成这项工作吗?
任何帮助和解释将不胜感激
谢谢
您不需要为此 运行 queue_draw()
。您也不应该在每次希望按钮更改颜色时都重新创建 GUI。这可能会把事情搞砸,因为在 gui()
中你创建了一个新的 window 并用 Gtk.main()
开始了一个新的主循环,导致许多主循环 运行 递归。这是你不想要的。
而是使用 button.set_name('green-button')
或 red-button
来更改颜色。除了从信号处理程序返回之外,不需要采取进一步的行动。
更好的方法是使用样式 类 而不是 ID — 您可能希望有多个绿色或红色按钮。在这种情况下,将 .green-button
和 .red-button
放入 CSS(而不是 #green-button
和 #red-button
)并使用它来更改颜色:
button.get_style_context().remove_class('green-button')
button.get_style_context().add_class('red-button')
反之亦然。
你把它弄得太复杂了,下面是一个简化版本,点击时按钮会变成绿色。
p.s。 像这样更改小部件的颜色应该是一个例外而不是规则,破坏用户主题通常不是一个好主意。
from gi.repository import Gtk
class CSSButtonApp(object):
def __init__(self):
self.mycolor = '''
GtkButton {
border-image: none;
background-image: none;
background-color: green;
color: white;
}
'''
self.window = Gtk.Window()
self.window.set_title('CSS Button')
self.window.set_default_size(200, 100)
self.window.set_border_width(10)
self.window.connect('destroy', lambda w: Gtk.main_quit())
button = Gtk.Button(label="My Button")
self.window.add(button)
provider = Gtk.CssProvider()
provider.load_from_data(self.mycolor)
button.connect("clicked", self.apply_css, provider)
self.window.show_all()
def apply_css(self, widget, provider):
Gtk.StyleContext.add_provider(widget.get_style_context(),
provider,
Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)
def main(self):
Gtk.main()
if __name__ == '__main__':
app = CSSButtonApp()
app.main()