簡體   English   中英

如何正確更改pygtk gtk.Button顏色

[英]How to change pygtk gtk.Button color PROPERLY

在我的應用程序中,我有大約500個按鈕,當采取特定操作時,所有按鈕都會更新其標簽和顏色。 當我注意到(通過使用cProfile和pdb)該問題是由更改按鈕顏色引起的時,我遇到了崩潰和性能問題:

self.button.modify_bg(gtk.STATE_PRELIGHT, color)
self.button.modify_bg(gtk.STATE_NORMAL, color)

這樣的500個調用需要5秒鍾的永恆時間(這也會凍結GUI),並且應用程序運行時間越長,它變得越慢。 以防萬一,我有一個功能強大的處理器和大量的可用內存。

以前,我嘗試按照docs中的建議使用EventBox。 但是,這只會更改按鈕后面的顏色,而不會更改按鈕表面的顏色:

import gtk

win = gtk.Window()
win.connect("destroy", gtk.main_quit)

btn = gtk.Button("test")
eb = gtk.EventBox()
eb.add(btn)
eb.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse("red"))

win.add(eb)
win.show_all()

gtk.main()

結果:

按鈕不是紅色

我還嘗試了替代方法,該方法涉及檢索和修改樣式。 這導致了與modify_bg相同的速度。 此外,我還在隨機位置出現了隨機崩潰,通常發生低級內存分配錯誤,例如從gtk釋放兩次。

import gtk

win = gtk.Window()
win.connect("destroy", gtk.main_quit)

btn = gtk.Button("test")
#copy the current style and replace the background
style = btn.get_style().copy()
style.bg[gtk.STATE_NORMAL] = gtk.gdk.color_parse("red")

#set the button's style to the one you created
btn.set_style(style)

win.add(btn)
win.show_all()

gtk.main()

似乎按鈕的顏色是由操作系統管理的,沒有緩慢,崩潰或不良結果,我無法找到解決方法。 我非常需要通過顏色傳達有關按鈕的重要信息。

那么如何正確更改按鈕的顏色呢?

我最終通過使用gtk.EventBox實現了自己的Button,該控件在其小部件樹內部包含gtk.Label 與使用按鈕不同,設置標簽顏色似乎與操作系統沒有沖突。

我還實現了一些便捷功能,例如set_label()

modify_bg仍然太慢,但不會導致崩潰。 通過檢查當前顏色是否與我要設置的顏色相同,我還為不變的按鈕節省了很多計算時間。

我的代碼很粗略,但是可以滿足我的目的。 隨時使其更強大和/或更靈活:

我的彩色按鈕

import gtk

class ColoredButton(gtk.EventBox):
    '''
    This class implements a simple unanimated button 
    whose color can be changed
    '''

    def __init__(self, widget = gtk.Label()):
        '''
        widget must be a gtk.Label
        this is not checked in this simple version
        '''

        #initialize superclass EventBox
        super(ColoredButton, self).__init__()

        #embed widget inside vbox and hbox 
        self.widget = widget 
        self.vbox = gtk.VBox(homogeneous=False, spacing=0) 
        self.hbox = gtk.HBox(homogeneous=False, spacing=0)
        self.hbox.pack_start(self.vbox, expand = True, fill=False)
        self.vbox.pack_start(self.widget, expand = True, fill = False)

        #draws a frame around the entire construct to make everything look more like a button
        self.frame = gtk.Frame()
        self.frame.add(self.hbox)

        #add the final "button" to this EventBox in order to handle events
        self.add(self.frame)

        #define which events should be reacted to, those constants can be found in pygtk docs
        self.add_events(gtk.gdk.BUTTON_RELEASE_MASK)
        self.add_events(gtk.gdk.BUTTON_PRESS_MASK)
        self.add_events(gtk.gdk.ENTER_NOTIFY_MASK)
        self.add_events(gtk.gdk.LEAVE_NOTIFY_MASK)

        #activate focus
        self.set_can_focus(True)

        #align the "button" text in the middle of the box
        self.widget.set_alignment(xalign=0.5, yalign=0.5)

    def show(self):
        super(ColoredButton, self).show()
        self.hbox.show()
        self.vbox.show()
        self.frame.show()
        self.widget.show()

    def set_label(self, label):
        self.set_text(label)

    def set_text(self, text):
        self.widget.set_text(text)

    def changeColor(self, color, state = gtk.STATE_NORMAL):
        if color is not None:
            currentcolor = self.style.bg[state]
            #too lazy to look up in docs if color != currentcolor also works
            if color.red != currentcolor.red or color.green != currentcolor.green or color.blue != currentcolor.blue:
                self.modify_bg(state, color)

    def changeTextColor(self, color, state = gtk.STATE_NORMAL):   
        if color is not None:
            currentcolor = self.style.bg[state]
            if color.red != currentcolor.red or color.green != currentcolor.green or color.blue != currentcolor.blue:
                self.widget.modify_fg(gtk.STATE_NORMAL, color)

def onButtonClick(widget, event = None):
    if event.button == 1:
        widget.set_label("left click")
    elif event.button == 2:
        widget.set_label("middle click")
    elif event.button == 3:
        widget.set_label("right click")

import gtk

w = gtk.Window()
w.connect('destroy', gtk.main_quit)

coloredbutton=ColoredButton(widget = gtk.Label("Hello there"))
coloredbutton.changeColor(gtk.gdk.color_parse("black"))
coloredbutton.changeTextColor(gtk.gdk.color_parse("yellow"))
coloredbutton.set_size_request(width = 100, height = 50)
coloredbutton.connect("button-release-event", onButtonClick)

w.add(coloredbutton)

w.show_all()
gtk.main()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM