如何在GTK中更新绘图区域

3
我正在尝试使用Python 2中的GTK制作时钟。 我目前拥有的版本只是一个基本的时钟,它将会更加复杂,但是我需要首先让它进行刷新。最终,它将成为屏幕保护程序。
我已经尝试理解queue_draw()的工作原理,但是我无法弄清楚。我对GTK很新,并且没有使用类的经验(虽然我正在努力)。我想这两个问题导致了我的问题。 可以有人帮我解决这个问题吗? :D 我知道有关此问题的帖子,但我仍然无法弄清楚如何使其工作 :( 谢谢
我正在使用Ubuntu 14.04, python 2。
这是我目前的代码:
#!/usr/bin/env python
import time
import gtk
import math

class Base:
    def destroy(self, widget, data=None):
        gtk.main_quit()

    def close(self, widget):
        self.window.destroy()

    def rotate(self, center, point, angle):
        #https://dev59.com/MGct5IYBdhLWcg3wWMFF
        px = point[0]
        py = point[1]
        rx = center[0] + (px - center[0]) * math.cos(math.radians(angle)) - (py - center[1]) * math.sin(math.radians(angle))
        ry = center[1] + (px - center[0]) * math.sin(math.radians(angle)) + (py - center[1]) * math.cos(math.radians(angle))
        return(rx, ry)

    # This function will be called whenever the drawing area is exposed:
    def expose_handler(self, widget, event) :
        w, h = widget.window.get_size()
        center = [int(w / 2), int(h / 2)]
        xgc = widget.window.new_gc()
                                      #%H for a 24 hour system as %I is for a 12 hour system
        TIME = time.strftime("%Y-%m-%d %I:%M:%S") #add this to get GMT time# , time.gmtime())
        H, M, S = TIME.split(" ")[1].split(":")
        H, M, S = int(H), int(M), int(S)

        Dial_radius = (h / 2 - ((h / 2) / 10)) / 3
        H_size, M_size, S_size = (Dial_radius / 2), Dial_radius, Dial_radius

        H_angle = H * (360 / 12) + (float(M) / 60) * (360 / 12)
        M_angle = M * (360 / 60) + (float(S) / 60) * (360 / 60)
        S_angle = S * (360 / 60)

        H_zero = [center[0], center[1] - H_size]
        M_zero = [center[0], center[1] - M_size]
        S_zero = [center[0], center[1] - S_size]

        Hx, Hy = self.rotate(center, H_zero, H_angle)
        Mx, My = self.rotate(center, M_zero, M_angle)
        Sx, Sy = self.rotate(center, S_zero, S_angle)

        #Hour
        xgc.set_rgb_fg_color(gtk.gdk.color_parse("red"))
        widget.window.draw_line(xgc, center[0], center[1], int(Hx), int(Hy))

        #Minute
        xgc.set_rgb_fg_color(gtk.gdk.color_parse("green"))
        widget.window.draw_line(xgc, center[0], center[1], int(Mx), int(My))

        #Second
        xgc.set_rgb_fg_color(gtk.gdk.color_parse("blue"))
        widget.window.draw_line(xgc, center[0], center[1], int(Sx), int(Sy))



    def __init__(self):
        self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
        self.window.set_position(gtk.WIN_POS_CENTER)
        #self.window.fullscreen()
        self.window.set_size_request(600, 400)

        self.vbox = gtk.VBox()
        self.window.add(self.vbox)

        # Create an area to draw in:
        self.drawing_area = gtk.DrawingArea()
        self.vbox.pack_start(self.drawing_area)
        self.drawing_area.show()

        self.drawing_area.connect("expose-event", self.expose_handler)
        self.drawing_area.show()
        self.window.show_all()
        self.window.connect("destroy", self.destroy)

    def main(self):
        gtk.main()

if __name__ == "__main__":
    base = Base()
    base.main()

我已将代码更新为acw1668的代码,现在它可以正常工作,再次感谢,看起来像这样:

#!/usr/bin/env python
import time
import gtk
import math
import glib

class Base:
    def destroy(self, widget, data=None):
        gtk.main_quit()

    def close(self, widget):
        self.window.destroy()

    def refresh_clock(self):
        self.drawing_area.queue_draw()
        return True

    def rotate(self, center, point, angle):
        #https://dev59.com/MGct5IYBdhLWcg3wWMFF
        px = point[0]
        py = point[1]
        rx = center[0] + (px - center[0]) * math.cos(math.radians(angle)) - (py - center[1]) * math.sin(math.radians(angle))
        ry = center[1] + (px - center[0]) * math.sin(math.radians(angle)) + (py - center[1]) * math.cos(math.radians(angle))
        return(rx, ry)

    # This function will be called whenever the drawing area is exposed:
    def expose_handler(self, widget, event) :
        w, h = widget.window.get_size()
        center = [int(w / 2), int(h / 2)]
        xgc = widget.window.new_gc()
                                      #%H for a 24 hour system as %I is for a 12 hour system
        TIME = time.strftime("%Y-%m-%d %I:%M:%S") #add this to get GMT time# , time.gmtime())
        H, M, S = TIME.split(" ")[1].split(":")
        H, M, S = int(H), int(M), int(S)

        Dial_radius = (h / 2 - ((h / 2) / 10)) / 3
        H_size, M_size, S_size = (Dial_radius / 2), Dial_radius, Dial_radius

        H_angle = H * (360 / 12) + (float(M) / 60) * (360 / 12)
        M_angle = M * (360 / 60) + (float(S) / 60) * (360 / 60)
        S_angle = S * (360 / 60)

        H_zero = [center[0], center[1] - H_size]
        M_zero = [center[0], center[1] - M_size]
        S_zero = [center[0], center[1] - S_size]

        Hx, Hy = self.rotate(center, H_zero, H_angle)
        Mx, My = self.rotate(center, M_zero, M_angle)
        Sx, Sy = self.rotate(center, S_zero, S_angle)

        #Hour
        xgc.set_rgb_fg_color(gtk.gdk.color_parse("red"))
        widget.window.draw_line(xgc, center[0], center[1], int(Hx), int(Hy))

        #Minute
        xgc.set_rgb_fg_color(gtk.gdk.color_parse("green"))
        widget.window.draw_line(xgc, center[0], center[1], int(Mx), int(My))

        #Second
        xgc.set_rgb_fg_color(gtk.gdk.color_parse("blue"))
        widget.window.draw_line(xgc, center[0], center[1], int(Sx), int(Sy))



    def __init__(self):
        self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
        self.window.set_position(gtk.WIN_POS_CENTER)
        #self.window.fullscreen()
        self.window.set_size_request(600, 400)

        self.vbox = gtk.VBox()
        self.window.add(self.vbox)

        # Create an area to draw in:
        self.drawing_area = gtk.DrawingArea()
        self.vbox.pack_start(self.drawing_area)
        self.drawing_area.show()

        self.drawing_area.connect("expose-event", self.expose_handler)
        self.drawing_area.show()
        self.window.show_all()
        self.window.connect("destroy", self.destroy)

    def main(self):
        glib.timeout_add_seconds(1, self.refresh_clock)
        gtk.main()

if __name__ == "__main__":
    base = Base()
    base.main()
1个回答

7
你可以使用glib.timeout_add_seconds(...)设置一个定时器,每秒调用queue_draw():
import glib

添加一个刷新时钟的功能:

def refresh_clock(self):
    self.drawing_area.queue_draw()
    return True

更新 main() 函数:

def main(self):
    glib.timeout_add_seconds(1, self.refresh_clock)
    gtk.main()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接