2013-07-17 109 views
1

以下代碼會截取屏幕截圖並記錄按鍵和鼠標移動。它使用wxpython作爲GUI框架。我正在使用python線程進行屏幕截圖和記錄服務。但是每當我關閉GUI應用程序。線程仍在運行。如何在關閉應用程序後停止這些線程?即使在關閉WxPython應用程序後,Python線程仍會運行

import wx 
import threading 
import sys 
import subprocess 
import time 

from pymouse import PyMouse 
from pymouse import PyMouseEvent 
from pykeyboard import PyKeyboard 
from pykeyboard import PyKeyboardEvent 

import pyscreenshot as ImageGrab 
from PIL import Image 
from PIL import ImageFont 
from PIL import ImageDraw 
import gtk.gdk 

import urllib2, urllib 
import Cookie 

MouseMovesCount = 0 
MouseClicksCount = 0 
KeyStrokesCount = 0 

class OD_App(wx.App): 
def OnInit(self): 
    frame = OD_MainFrame ("Login", (0, 0), (350, 200)) 
    self.SetTopWindow(frame) 

    loginPanel = OD_LoginPanel (frame) 
    self.Bind(wx.EVT_CLOSE, self.OnCloseWindow) 
    frame.Show() 
    return True 

def OnCloseWindow (self, event): 
    self.Destroy() 

class OD_MainFrame(wx.Frame): 
def __init__(self, title, pos, size): 
    wx.Frame.__init__(self, None, -1, title, pos, size) 
    self.CreateStatusBar() 

class OD_LoginPanel(wx.Panel): 
def __init__(self, frame): 
    self.panel = wx.Panel(frame) 
    self.frame = frame 

    self.frame.SetStatusText("Authentication required!") 
    self.showLoginBox() 

def showLoginBox (self): 
    # Create the sizer 
    sizer = wx.FlexGridSizer(rows=3, cols=2, hgap=5, vgap=15) 

    # Username 
    self.txt_Username = wx.TextCtrl(self.panel, 1, size=(150, -1)) 
    lbl_Username = wx.StaticText(self.panel, -1, "Username:") 
    sizer.Add(lbl_Username,0, wx.LEFT|wx.TOP| wx.RIGHT, 50) 
    sizer.Add(self.txt_Username,0, wx.TOP| wx.RIGHT, 50) 

    # Password 
    self.txt_Password = wx.TextCtrl(self.panel, 1, size=(150, -1), style=wx.TE_PASSWORD) 
    lbl_Password = wx.StaticText(self.panel, -1, "Password:") 
    sizer.Add(lbl_Password,0, wx.LEFT|wx.RIGHT, 50) 
    sizer.Add(self.txt_Password,0, wx.RIGHT, 50) 

    # Submit button 
    btn_Process = wx.Button(self.panel, -1, "&Login") 
    self.panel.Bind(wx.EVT_BUTTON, self.OnSubmit, btn_Process) 
    sizer.Add(btn_Process,0, wx.LEFT, 50) 

    self.panel.SetSizer(sizer) 

def OnSubmit(self, event): 
    username = self.txt_Username.GetValue() 
    password = self.txt_Password.GetValue() 
    mydata = [('username',username),('password',password)] 
    mydata = urllib.urlencode(mydata) 
    path = 'http://xyz/logincheck.php' #temporary db for testing 
    req = urllib2.Request(path, mydata) 
    req.add_header("Content-type", "application/x-www-form-urlencoded") 
    page = urllib2.urlopen(req).read() 
    if page == "true": 
     self.frame.SetStatusText("Authentication Success!") 
     self.show_other(username) 
    else: 
     self.frame.SetStatusText("Authentication Failed!") 

def OnCloseWindow (self, event): 
    self.Destroy() 

def show_other(self,username): 
    self.frame.Destroy() 
    userpanel = OD_UserPanel() 
    return True 

class OD_UserPanel(wx.App): 
def OnInit(self): 
    userpanel = wx.Frame(None,-1) 
    self.Bind(wx.EVT_CLOSE, self.OnCloseWindow) 
    #user_greeting = 'Welcome ' + username + '!' 
    #username = wx.StaticText(userpanel, -1, user_greeting , style=wx.ALIGN_CENTRE) 
    userpanel.Show() 
    mouse_eventer = mouse_event() 
    mouse_eventer.start() 
    keyboard_eventer = key_event() 
    keyboard_eventer.start() 
    screenshot_eventer = screenshot_thread() 
    screenshot_eventer.start() 
    return True 
def OnCloseWindow (self, event): 
    quit() 
    event.Skip() 
    raise SystemExit 
class mouse_event(PyMouseEvent): 
    def move(self, x, y): 
     global MouseMovesCount 
     MouseMovesCount = MouseMovesCount + 1 
     print MouseMovesCount 
    def click(self, x, y, button, press): 
     global MouseClicksCount 
      if press: 
     MouseClicksCount = MouseClicksCount + 1 
       print MouseClicksCount 
      else: 
       MouseClicksCount = MouseClicksCount + 1 
       print MouseClicksCount 

class key_event(PyKeyboardEvent): 
    global screenshot_eventer 
    def key_press(self, key): 
     global KeyStrokesCount 
     KeyStrokesCount = KeyStrokesCount + 1 
     print KeyStrokesCount 
    def key_release(self, key): 
     global KeyStrokesCount 
     KeyStrokesCount = KeyStrokesCount + 1 
     print KeyStrokesCount 

class screenshot_thread(threading.Thread): 
    def __init__(self): 
    super(screenshot_thread, self).__init__() 
    self.state = True 
    # Attributes 
    def run(self): 
    self.take_shot() 
    def stop(self): 
    self.state = False 
    threading.Thread._Thread__stop() 
    def take_shot(self): 
    while self.state==True: 
    time.sleep(10) 
    subprocess.call(['scrot']) 
if __name__ == '__main__': 
    app = OD_App() 
    app.MainLoop() 

回答

2

請勿撥打threading.Thread._Thread__stop!前導下劃線表示這是內部api,它不能保證甚至存在(事實上,在python3中它已經不存在了)。

如果您希望THEAD被自動銷燬,將其設置爲惡魔的:

def __init__(self): 
    super(screenshot_thread, self).__init__() 
    self.daemon = True 

這將導致它當最後一個非惡魔的線程已停止自動銷燬。或者,就你的情況而言,只需將狀態設置爲False即可使線程在10秒後退出。

+0

我刪除了'threading.Thread._Thread__stop',並沒有實例化screenshot_thread類。但仍然在key_event和mouse_event類中遇到問題。 – user2591965

0

您在screenshot_thread類中定義了stop方法,但不使用它。在方法OnCloseWindow中調用它應該完成這項工作。

+0

在OnCloseWindow中嘗試停止方法。但是這並不能解決問題。 – user2591965

+1

正如user2591965所說,不要使用'threading.Thread._Thread__stop'。你爲什麼要調用'raise SystemExit'?這可能會阻止正確清理。如果所有窗口都關閉,你的應用程序應該自行退出。 – mprochnow

相關問題