如何在线程中改变变量?

0 投票
2 回答
7287 浏览
提问于 2025-04-16 08:19

这是我的情况。假设我想创建一个线程,这个线程会不断打印数字1。当我点击一个按钮时,这个数字应该变成2。我的问题是,我不太确定如何在一个已经运行的线程中改变一个变量。以下是我的代码:

import wx
from threading import Thread
import time

class testThread(Thread):
    def __init__(self, parent):
        self.parent = parent
        Thread.__init__(self)
        self.start()

    def run(self):
        while 1:
            x = 1
            print x
            time.sleep(1)

class testGUI(wx.Frame): 
    def __init__(self): 
        wx.Frame.__init__(self, None, -1, "Test", size=(500,270)) 
        panel = wx.Panel(self, -1)

        self.buttonStart = wx.Button(panel, -1, label="Start thread", pos=(0,0))
        self.buttonChange = wx.Button(panel, -1, label="Change var", pos=(0,30))
        panel.Bind(wx.EVT_BUTTON, self.startThread, id=self.buttonStart.GetId())
        panel.Bind(wx.EVT_BUTTON, self.changeVar, id=self.buttonChange.GetId())

    def startThread(self, event):
        testThread(self)

    def changeVar(self, event):
        # DO SOMETHING HERE THAT CHANGES 'x' IN THREAD TO 2...
        pass

if __name__ == '__main__': 
    app = wx.App(redirect=False)
    frame = testGUI() 
    frame.Show(True) 
    app.MainLoop()

所以我的问题是,我在函数changeVar里面应该写什么,才能修改正在运行的线程中的变量x的内容呢?提前谢谢!

2 个回答

1

其实你根本不需要用到线程。wx里有一个叫做wx.Timer的东西,它可以让你在同一个线程里按一定时间间隔调用你的函数。很可能wx里还有其他功能可以满足你的需求。

import wx

class testGUI(wx.Frame): 
    def __init__(self): 
        wx.Frame.__init__(self, None, -1, "Test", size=(500,270)) 
        panel = wx.Panel(self, -1)
        self.buttonStart = wx.Button(panel, -1, label="Start timer", pos=(0,0))
        self.buttonChange = wx.Button(panel, -1, label="Change var", pos=(0,30))
        panel.Bind(wx.EVT_BUTTON, self.startTimer, id=self.buttonStart.GetId())
        panel.Bind(wx.EVT_BUTTON, self.changeVar, id=self.buttonChange.GetId())
        self.value = 1
        self.timer = wx.Timer(self)
        self.Bind(wx.EVT_TIMER, self.printer, self.timer)

    def startTimer(self, event):
        self.timer.Start(1000) # 1 second

    def printer(self, event):
        print self.value

    def changeVar(self, event):
        self.value = 2

if __name__ == '__main__': 
    app = wx.App(redirect=False)
    frame = testGUI() 
    frame.Show(True) 
    app.MainLoop()
2

你不能改变局部变量。

你可以这样做:

class testThread(Thread):
    def __init__(self, parent):
        self.parent = parent
        Thread.__init__(self)
        self.start()

    def run(self):
        self.value = 1
        while 1:
            print self.value
            time.sleep(1)

class testGUI(wx.Frame): 
    def __init__(self): 
        wx.Frame.__init__(self, None, -1, "Test", size=(500,270)) 
        panel = wx.Panel(self, -1)

        self.buttonStart = wx.Button(panel, -1, label="Start thread", pos=(0,0))
        self.buttonChange = wx.Button(panel, -1, label="Change var", pos=(0,30))
        panel.Bind(wx.EVT_BUTTON, self.startThread, id=self.buttonStart.GetId())
        panel.Bind(wx.EVT_BUTTON, self.changeVar, id=self.buttonChange.GetId())

    def startThread(self, event):
        self.the_thread = testThread(self)

    def changeVar(self, event):
        # DO SOMETHING HERE THAT CHANGES 'x' IN THREAD TO 2...
        self.the_thread.value = 2

if __name__ == '__main__': 
    app = wx.App(redirect=False)
    frame = testGUI() 
    frame.Show(True) 
    app.MainLoop()

撰写回答