Этот пример взят из проекта, над которым я работаю.Мой клиент использует программное обеспечение, которое использует его веб-камеру, чтобы делать снимки, если движение обнаруживается в его представлении.Проблема заключается в том, что программное обеспечение не может отправить изображения по электронной почте в его учетную запись, когда они были приняты.Я написал этот проект для отслеживания папки, в которой сохраняются снимки, и настроил ее на отправку любых новых снимков в электронном письме на указанную учетную запись. Таким образом, он получит предупреждение в своей ячейке, как это происходит, вместе со снимкомиз того, что было поймано в движение.Да, я осознаю тот факт, что существует множество приложений, в которых эта функция включена в их программное обеспечение для веб-камеры, но мой клиент нанял меня, чтобы он мог избежать необходимости заменять текущее программное обеспечение, поскольку ему удобно пользоваться.
Есть два шага к функции Start ().Шаг 1 - это задержка перед запуском монитора, Шаг 2 - запуск самого монитора.До сих пор я не могу заставить функцию Stop () убить Шаг 1 из-за обратного отсчета в строке состояния графического интерфейса.
Функция Monitor.Stop () работает нормально, когда запускается сама в консоли, ноэто не работает, когда он запускается из обработчика событий self.OnConnect () в интерфейсе?Я пробовал несколько вариантов структур потоков, используя: threading, thread, kthread и т. Д., Но все они закончились одним и тем же результатом.
В идеале я хочу нажать Connect в меню File -> Connect label label toОтключение -> монитор запускается с шага 1 -> StatusBar отображает время, оставшееся до шага 2.
На этом этапе я хочу иметь возможность остановить обратный отсчет, нажав Отключить в меню Файл, но когда я нажимаю на него, обратный отсчетпродолжается?Каждый вариант функций потока, которые я пробовал, успешно останавливал поток при запуске из консоли, но я до сих пор не могу понять, почему не удается остановить обратный отсчет при вызове из моего графического интерфейса?
AnyПомощь будет принята с благодарностью!: D
Кстати, обязательно замените две записи "C: \ Replace \ With \ Valid \ Path" в нижней части скрипта на допустимый путь в вашей системе, если вы решили запуститьит.
import os, sys, thread, time, wx
class Frame(wx.Frame):
def __init__(self, parent, id=-1, title="A Frame", path="", pos=wx.DefaultPosition, size=wx.DefaultSize, style=wx.DEFAULT_FRAME_STYLE):
wx.Frame.__init__(self, parent, id, title, pos, size, style)
self.path = path
self.StatusBar = wx.StatusBar(self, -1)
self.StatusBar.SetFieldsCount(3)
self.StatusBar.SetStatusWidths([-2, -1, -1])
self.InitMenuBar()
def InitMenuBar(self):
menuBar = wx.MenuBar()
menuFile = wx.Menu()
menuHelp = wx.Menu()
self._Connect = menuFile.Append(101, "&Connect", kind=wx.ITEM_CHECK)
menuFile.AppendSeparator()
menuFile.Append(104, "E&xit")
menuBar.Append(menuFile, "&File")
menuBar.Append(menuHelp, "&Help")
self.SetMenuBar(menuBar)
self.Bind(wx.EVT_MENU, self.OnConnect, self._Connect)
def OnConnect(self, event):
#print [event.IsChecked()]
mon = Monitor("", "", "", self.path, "60", self.StatusBar)
if event.IsChecked():
print "Set Menu Label Disconnected"
self._Connect.SetItemLabel("Disconnect")
print "Start Monitor"
mon.Start()
print "Start Finished"
else:
print "Set Menu Label Connected"
self._Connect.SetItemLabel("Connect")
print "Stop Monitor"
mon.Stop()
print "Stop Finished"
class Monitor:
def __init__(self, email, password, recipient, path, timeout, statusBar=None):
self.email = email
self.password = password
self.recipient = recipient
self.path = path
self.timeout = timeout
self.statusBar = statusBar
#self.lock = thread.allocate_lock()
def Start(self):
#self.lock.acquire()
self.running = True
thread.start_new_thread(self.Run, ())
#self.lock.release()
def Stop(self):
#self.lock.acquire()
self.running = False
#self.lock.release()
def IsRunning(self):
return self.running
def Run(self):
start = NewestByModTime(self.path)
count = int(self.timeout)
while self.running:
#print self.running
# Step 1 - Delay the start of the monitor for X amount of seconds, updating the
# statusbar/console each second to relfect a countdown. remove one from count each
# loop until the count equals 0, than continue on to Step 2.
if count > 0:
if self.statusBar:
self.statusBar.SetStatusText("Monitoring will begin in %s seconds" % (count))
else:
sys.stdout.write("Monitoring will begin in %s seconds\r" % (count))
#sys.stdout.flush()
count -= 1
time.sleep(1)
# Step 2 - Start the monitor function which monitors the selected folder for new
#files. If a new file is detected, send notification via email with the new file
#as an attachment. (for this project, files in the folder will always be jpg images)
# *NOTE* I Have not tested the Stop() function during Step 2 just yet, but I would
# assume it would fail just the same as . *NOTE*
if count == 0:
current = NewestByModTime(self.path)
if current[1] > start[1]:
print "Activity Detected"
start = current
print "Sending Notification Email"
#sendMail(self.email, self.password, self.recipient, "JERK ALERT!!",
# "Some jerkoff is in your place right now, wanna see who it is??", "%s\\%s" % (self.path, start[0]))
print "Notification Email Sent!"
print
self.running = False
def NewestByModTime(path):
stat = ["", 0]
for a in os.listdir(path):
new = os.path.getmtime("%s\\%s" %(path, a))
if new > stat[1]:
stat = [a, new]
return stat
if __name__ == "__main__":
# Run GUI
app = wx.PySimpleApp()
frame = Frame(None, -1, "Test Frame", "C:\\Replace\\With\\Valid\\Path", size=(800, 600))
frame.Show()
app.MainLoop()
del app
## Run Console
#mon = Monitor("", "", "", "C:\\Replace\\With\\Valid\\Path", "60", None)
#mon.Start()
#time.sleep(10)
#mon.Stop()