gpt4 book ai didi

python - 初级Python线程问题

转载 作者:太空狗 更新时间:2023-10-29 21:27:41 26 4
gpt4 key购买 nike

作为使用 Python(使用 pyGTK)进行 GUI 开发的新手,我刚刚开始学习线程。为了测试我的技能,我编写了一个带有开始/停止按钮的简单的小 GTK 界面。目标是当它被点击时,一个线程启动,快速增加文本框中的数字,同时保持 GUI 响应。

我的 GUI 工作得很好,但线程有问题。这可能是一个简单的问题,但我的想法是为了一天而烦恼。下面我首先粘贴了 Python 解释器的引用,然后是代码。你可以去http://drop.io/pxgr5id下载。我正在使用 bzr 进行版本控制,因此如果您想进行修改并重新删除它,请提交更改。我还将代码粘贴在 http://dpaste.com/113388/ 处,因为它可以有行号,而这个 Markdown 的东西让我很头疼。

美国东部时间 1 月 27 日 15:52 更新:可以在这里找到稍微更新的代码:http://drop.io/threagui/asset/thread-gui-rev3-tar-gz

回溯

crashsystems@crashsystems-laptop:~/Desktop/thread-gui$ python threadgui.pybtnStartStop clicked
Traceback (most recent call last):
File "threadgui.py", line 39, in on_btnStartStop_clicked
self.thread.stop()
File "threadgui.py", line 20, in stop
self.join()
File "/usr/lib/python2.5/threading.py", line 583, in join
raise RuntimeError("cannot join thread before it is started")
RuntimeError: cannot join thread before it is started
btnStartStop clicked
threadStop = 1
btnStartStop clicked
threadStop = 0
btnStartStop clicked
Traceback (most recent call last):
File "threadgui.py", line 36, in on_btnStartStop_clicked
self.thread.start()
File "/usr/lib/python2.5/threading.py", line 434, in start
raise RuntimeError("thread already started")
RuntimeError: thread already started
btnExit clicked
exit() called

代码

#!/usr/bin/bash
import gtk, threading

class ThreadLooper (threading.Thread):
def __init__ (self, sleep_interval, function, args=[], kwargs={}):
threading.Thread.__init__(self)
self.sleep_interval = sleep_interval
self.function = function
self.args = args
self.kwargs = kwargs
self.finished = threading.Event()

def stop (self):
self.finished.set()
self.join()

def run (self):
while not self.finished.isSet():
self.finished.wait(self.sleep_interval)
self.function(*self.args, **self.kwargs)

class ThreadGUI:
# Define signals
def on_btnStartStop_clicked(self, widget, data=None):
print "btnStartStop clicked"
if(self.threadStop == 0):
self.threadStop = 1
self.thread.start()
else:
self.threadStop = 0
self.thread.stop()
print "threadStop = " + str(self.threadStop)

def on_btnMessageBox_clicked(self, widget, data=None):
print "btnMessageBox clicked"
self.lblMessage.set_text("This is a message!")
self.msgBox.show()

def on_btnExit_clicked(self, widget, data=None):
print "btnExit clicked"
self.exit()

def on_btnOk_clicked(self, widget, data=None):
print "btnOk clicked"
self.msgBox.hide()

def on_mainWindow_destroy(self, widget, data=None):
print "mainWindow destroyed!"
self.exit()

def exit(self):
print "exit() called"
self.threadStop = 1
gtk.main_quit()

def threadLoop(self):
# This will run in a thread
self.txtThreadView.set_text(str(self.threadCount))
print "hello world"
self.threadCount += 1

def __init__(self):
# Connect to the xml GUI file
builder = gtk.Builder()
builder.add_from_file("threadgui.xml")

# Connect to GUI widgets
self.mainWindow = builder.get_object("mainWindow")

self.txtThreadView = builder.get_object("txtThreadView")
self.btnStartStop = builder.get_object("btnStartStop")
self.msgBox = builder.get_object("msgBox")
self.btnMessageBox = builder.get_object("btnMessageBox")
self.btnExit = builder.get_object("btnExit")
self.lblMessage = builder.get_object("lblMessage")
self.btnOk = builder.get_object("btnOk")

# Connect the signals
builder.connect_signals(self)

# This global will be used for signaling the thread to stop.
self.threadStop = 1

# The thread
self.thread = ThreadLooper(0.1, self.threadLoop, (1,0,-1))
self.threadCounter = 0

if __name__ == "__main__":
# Start GUI instance
GUI = ThreadGUI()
GUI.mainWindow.show()
gtk.main()

最佳答案

如果您想正确地使用 PyGTK 进行线程处理,则有点棘手。基本上,您不应该从主线程以外的任何其他线程中更新 GUI(GUI 库中的常见限制)。通常这是在 PyGTK 中使用排队消息机制(用于 worker 和 GUI 之间的通信)完成的,这些消息使用超时功能定期读取。一旦我在本地 LUG 上就此主题进行了演示,您就可以从 Google Code repository 获取此演示文稿的示例代码。 .查看 forms/frmmain.py 中的 MainWindow 类,特别是方法 _pulse() 以及 on_entry_activate( )(线程在那里启动加上空闲计时器被创建)。

def on_entry_activate(self, entry):
text = entry.get_text().strip()
if text:
store = entry.get_completion().get_model()
if text not in [row[0] for row in store]:
store.append((text, ))
thread = threads.RecommendationsFetcher(text, self.queue)# <- 1
self.idle_timer = gobject.idle_add(self._pulse)# <- 2
tv_results = self.widgets.get_widget('tv_results')
model = tv_results.get_model()
model.clear()
thread.setDaemon(True)# <- 3
progress_update = self.widgets.get_widget('progress_update')
progress_update.show()
thread.start()# <- 4

这样,应用程序会在“空闲”(通过 GTK 方式)时更新 GUI,而不会导致卡住。

  • 1: 创建线程
  • 2:创建空闲计时器
  • 3:守护线程,这样应用程序就可以在不等待线程完成的情况下关闭
  • 4:启动线程

关于python - 初级Python线程问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/482263/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com