在Gtk3(pygobject)和python3中更新/刷新Widget

时间:2015-04-17 14:10:59

标签: python-3.x gtk3 pygobject

我希望点击它时按钮的颜色会发生变化。
或者更一般我想更新/刷新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编程新手,但我的理解是, 这就是它被困的地方#34;在等待用户输入的大部分时间 或者删除小部件并在同一空间放置一个新小部件来完成工作? 非常感谢任何帮助和解释 感谢

2 个答案:

答案 0 :(得分:3)

您无需为此运行queue_draw()。每次希望按钮改变颜色时,也不应重新创建GUI。这可能会搞砸了,因为在gui()中你创建了一个新窗口并用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')

反之亦然。

答案 1 :(得分:1)

你让它变得非常复杂,下面是一个简化的版本,点击后按钮会变绿。

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()