Делайте скриншоты через фиксированные промежутки времени с помощью Python, используя threading.Timer - PullRequest
7 голосов
/ 06 мая 2011

Я пишу простое приложение с графическим интерфейсом с pyGTK, чтобы делать скриншоты рабочего стола через фиксированные интервалы. Для составления расписания выстрелов я использую класс threading.Timer, а для выстрелов я использую os.system для scrot.

Когда я нажимаю кнопку «Начать делать скриншоты», вызывается метод GlapseMain.startScreenshots. Когда я нажимаю кнопку «Снять снимок экрана», вызывается метод GlapseMain.stopScreenshots.

Дело в том, что пока работает приложение GTK, скриншот не берется, хотя и должен. Когда я нажимаю кнопку закрытия, он начинает делать снимки экрана бесконечно.

Вот мой код:

#!/usr/bin/env python
# -*- coding: utf8  -*-

import threading
import os

class GlapseMain:

def __init__(self):
    self.outputDir = os.getenv('HOME')
    self.quality = 80
    self.interval = 10
    self.numDigits = 15
    self.currentShot = 0

def startScreenshots(self, output, quality, interval):
    print 'Starting taking screenshots...'
    print 'Output folder: ' + str(output)
    print 'Quality: ' + str(quality)
    print 'Interval: ' + str(interval)

    # Update attributes
    self.outputDir = output
    self.quality = quality
    self.interval = interval
    self.currentShot = 0

    # Create timer (first screenshot scheduled 1s ahead)
    self.timer = threading.Timer(1.0, self._takeScreenshot)
    self.timer.start()


def stopScreenshots(self):
    print 'Stopped taking screenshots.'

    self.timer.cancel()


def _takeScreenshot(self):
    # Build scrot command
    fileNumber = str(self.currentShot)
    fileNumber = fileNumber.zfill(self.numDigits - len(fileNumber))
    fileName = 'scr-' + fileNumber + '.jpg'

    command = 'scrot -q ' + str(self.quality) + ' ' + self.outputDir + os.sep + fileName

    print 'Taking screenshot: ' + command + '...'

    os.system(command)

    # Schedule next screenshot
    self.currentShot = self.currentShot + 1
    self.timer = threading.Timer(self.interval, self._takeScreenshot)
    self.timer.start()

Мой вывод выглядит примерно так:

Starting taking screenshots...
Output folder: /home/david/glapse-screens
Quality: 80.0
Interval: 2.0
Stopped taking screenshots.
Taking screenshot: scrot -q 80.0 /home/david/glapse-screens/scr-00000000000000.jpg...
Closing gLapse...
Taking screenshot: scrot -q 80.0 /home/david/glapse-screens/scr-00000000000001.jpg...
Taking screenshot: scrot -q 80.0 /home/david/glapse-screens/scr-00000000000002.jpg...
Taking screenshot: scrot -q 80.0 /home/david/glapse-screens/scr-00000000000003.jpg...
Taking screenshot: scrot -q 80.0 /home/david/glapse-screens/scr-00000000000004.jpg...
Taking screenshot: scrot -q 80.0 /home/david/glapse-screens/scr-00000000000005.jpg...
Taking screenshot: scrot -q 80.0 /home/david/glapse-screens/scr-00000000000006.jpg...
Taking screenshot: scrot -q 80.0 /home/david/glapse-screens/scr-00000000000007.jpg...

Надеюсь, вы могли бы помочь мне, большое спасибо.

Edit:

Я изменил подход и теперь использую темы:

def startScreenshots(self, output, quality, interval):
    print 'Starting taking screenshots...'
    print 'Output folder: ' + str(output)
    print 'Quality: ' + str(quality)
    print 'Interval: ' + str(interval)

    # Update attributes
    self.outputDir = output
    self.quality = quality
    self.interval = interval
    self.currentShot = 0

    # Start a thread to take screenshots
    self.done = False
    self.thread = threading.Thread(target=self._takeScreenshot)
    self.thread.start()

def stopScreenshots(self):
    print 'Stopped taking screenshots.'
    self.done = True
    self.thread.join()


def _takeScreenshot(self):
    # Run until we're done
    while not self.done:
        # Build scrot command
        fileNumber = str(self.currentShot)
        fileNumber = fileNumber.zfill(self.numDigits - len(fileNumber))
        fileName = 'scr-' + fileNumber + '.jpg'

        command = 'scrot -q ' + str(self.quality) + ' ' + self.outputDir + os.sep + fileName

        print 'Taking screenshot: ' + command + '...'

        os.system(command)

        # Schedule next screenshot
        print 'Scheduling next screenshot...'
        self.currentShot = self.currentShot + 1
        time.sleep(self.interval)

Она печатает сообщение, но не выполняет инструкцию os.system, пока я не нажму кнопку остановки.

1 Ответ

4 голосов
/ 06 мая 2011

Для ответа:

Вам также нужно вызвать

gtk.gdk.threads_init()

перед вызовом gtk.main (), если вы хотите потоки с gtk


ПустьВместо этого _takeScreenshot () имеет цикл while и не запускает новый поток для следующего снимка экрана.У вас уже есть рабочий поток для этого, например,

Вам также нужен поток вместо таймера

def _takeScreenshot(self):
    while self.notDone:
         # take screen shot
         # ..
         time.sleep(self.interval)

Затем в вашем методе отмены сделайте что-то вроде:

def stopScreenshots(self):
    self.notDone = False
    self.timer.join() # wait for thread to finish 
...