创建在gtk中自动更新的控件,同时能控制其他控件
好的,在我学习Python的过程中,我在一个副项目中尝试构建一个gtk应用程序,用来监控水温,并且每10秒更新一次gtk应用中的文本框。我还想要一个倒计时器,可以在gtk中显示,并且每秒刷新一次。我已经用glade和gtk搭建了一个图形界面,但遇到了应用程序卡死和无响应的问题。经过一番阅读,我发现我需要使用线程。可是我对线程一无所知,想知道这里有没有人能帮我。我真的很想学习在使用gtk和Glade作为图形界面构建工具时,如何使用线程。我找到了一段使用gtk的代码,但我还是遇到了一些问题。能不能请大家帮帮我?
import sys
import time
import gtk
from threading import Thread
threadcount=0
class Test (Thread):
def __init__ (self,button, count=0):
Thread.__init__(self)
self.count = count
self.button=button
def run (self):
for i in range(0,10):
time.sleep(1)
# Acquire and release the lock each time.
gtk.threads_enter()
self.button.set_label("Thread %002d - %d" % (self.count,i))
gtk.threads_leave()
gtk.threads_enter()
self.button.set_label(" Start Thread ")
gtk.threads_leave()
def start_new_thread (button, data=None):
global threadcount
threadcount += 1
a = Test(button,threadcount)
a.start()
def hello(*args):
""" Callback function that is attached to the button """
print "Hello World"
window.destroy()
def destroy(*args):
""" Callback function that is activated when the program is destoyed
"""
window.hide()
gtk.main_quit()
# Initialize threads
gtk.threads_init()
window = gtk.Window(gtk.WINDOW_TOPLEVEL)
window.connect("destroy", destroy)
window.set_border_width(10)
button = gtk.Button(" Start Thread ")
button.connect("clicked", start_new_thread,button)
window.add(button)
button.show()
window.show_all()
gtk.threads_enter()
gtk.main()
gtk.threads_leave()
这是我尝试使用的代码,简化到只有计时器功能。我不太确定怎么让所有东西都能正常工作。我读到过一些关于gobjects的内容,但我对那方面了解得更少。
import gtk
import time
import sys
import os
import threading
TIME = 0
LOCK = threading.Lock()
class Timer(threading.Thread):
def __init__(self, nMinutes):
threading.Thread.__init__(self)
self.nMin = nMin
def run(self):
global TIME
nSeconds = self.nMinutes*60
TIME = nSeconds
startTime = time.time()
while TIME != 0:
ElapTime = time.time() - startTime
LOCK.acquire()
TIME = nSeconds - ElapTime
LOCK.release()
class GUI_Timer_Update(threading.Thread):
def __init__(self, TIME):
threading.Thread.__init__(self)
self.TIME = TIME
def run(self):
while TIME != 0:
timeFormatted = self.format_time(TIME)
LOCK.acquire()
# Code that updates the GUI after formatting it
LOCK.release()
def format_time(self, x):
minutes, seconds_rem = divmod(x, 60)
if minutes >= 60:
hours, minutes_rem = divmod(minutes, 60)
return "%02d:%02d:%02d" % (hours, minutes_rem, seconds_rem)
else:
minutes, seconds_rem = divmod(x, 60)
return "00:%02d:%02d" % (minutes, seconds_rem)
class GUI(object):
def __init__(self):
self.builder = gtk.Builder()
self.builder.add_from_file("Timer.glade")
self.window1 = self.builder.get_object("window1")
self.window1.show()
self.builder.connect_signals(self)
def on_window1_destroy(self, object, data=None):
print "quit on destroy"
gtk.main_quit()
def on_startTimer_clicked(self, widget):
self.timer = self.builder.get_object("timer").get_text() # get time in minutes from timer text box
self.timer = int(self.timer) # convert the text to an int
def on_timerReset_clicked(self, widget):
self.builder.get_object("timer").set_text('')
self.builder.get_object("TIME").set_text('')
def main(self):
gtk.main()
if __name__ == "__main__":
gui = GUI()
gui.main()
我还想加入一个停止/暂停按钮。任何帮助都非常感谢。谢谢!
1 个回答
0
好的,我把我的代码修改成这样了:
import gtk, time, sys, os, gobject
COUNTER = 0
COUNTER2 = 0
class GUI(object):
def __init__(self):
self.builder = gtk.Builder()
self.builder.add_from_file("Timer.glade")
self.window1 = self.builder.get_object("window1")
self.window1.show()
self.builder.connect_signals(self)
self.g = 0
def on_window1_destroy(self, object, data=None):
print "quit on destroy"
gtk.main_quit()
def on_startTimer_clicked(self, widget):
global COUNTER
self.time = self.builder.get_object("time").get_text()
COUNTER = int(self.time)
self.g = gobject.timeout_add(1000, self.timer)
def on_startTimer2_clicked(self, widget):
global COUNTER2
self.time2 = self.builder.get_object("time2").get_text()
COUNTER2 = int(self.time2)
self.g2 = gobject.timeout_add(1000, self.timer2)
def timer2(self):
global COUNTER2
while COUNTER2 >= 0:
if COUNTER2 != 0:
self.builder.get_object("time2").set_text(str(self.format_time(COUNTER2)))
COUNTER2 -=1
return True
else:
self.builder.get_object("time2").set_text("Finished")
return False
def timer(self):
global COUNTER
while COUNTER >= 0:
if COUNTER != 0:
self.builder.get_object("time").set_text(str(self.format_time(COUNTER)))
COUNTER -=1
return True
else:
self.builder.get_object("time").set_text("Finished")
return False
def format_time(self, x):
minutes, seconds_rem = divmod(x, 60)
if minutes >= 60:
hours, minutes_rem = divmod(minutes, 60)
return "%02d:%02d:%02d" % (hours, minutes_rem, seconds_rem)
else:
minutes, seconds_rem = divmod(x, 60)
return "00:%02d:%02d" % (minutes, seconds_rem)
def main(self):
gtk.main()
if __name__ == "__main__":
gui = GUI()
gui.main()
这个视频系列让我开始理解如何使用 gobject.timeout_add()。谢谢 user4815162342 的建议。