使用threading.Timer使用Python以固定的时间间隔拍摄屏幕截图

使用threading.Timer使用Python以固定的时间间隔拍摄屏幕截图,python,timer,gtk,pygtk,screenshot,Python,Timer,Gtk,Pygtk,Screenshot,我正在用pyGTK编写一个简单的GUI应用程序,以固定的时间间隔拍摄桌面截图。为了安排快照,我使用threading.Timer类,为了拍摄快照,我使用对scrot的os.system调用 当我单击开始截图按钮时,会调用GlapseMain.startScreenshots方法。当我单击停止截图按钮时,会调用GlapseMain.stopScreenshots方法 问题是,当GTK应用程序运行时,没有截图,尽管它应该这样做。当我点击close按钮时,它开始无限地截图 这是我的密码: #!/usr

我正在用pyGTK编写一个简单的GUI应用程序,以固定的时间间隔拍摄桌面截图。为了安排快照,我使用threading.Timer类,为了拍摄快照,我使用对scrot的os.system调用

当我单击开始截图按钮时,会调用GlapseMain.startScreenshots方法。当我单击停止截图按钮时,会调用GlapseMain.stopScreenshots方法

问题是,当GTK应用程序运行时,没有截图,尽管它应该这样做。当我点击close按钮时,它开始无限地截图

这是我的密码:

#!/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...
希望你能帮助我,非常感谢

编辑:

我已经改变了方法,现在我正在使用线程:

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指令。

要响应:

你也需要打电话

gtk.gdk.threads_init()
如果希望使用gtk执行线程,则调用前面的gtk.main()


让_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 

while循环不会冻结GUI?不,它运行在你的线程中,而不是主应用程序线程中。这就是线程的要点:)请注意,我假设您使用的是线程而不是计时器,因为计时器将冻结GUI。我用线程方法编辑了我的消息,但它只打印截图消息。直到我按下“取消”按钮,屏幕才会被截图。编辑了我的答案。您还需要在gtk.main()之前调用gtk.threads_init()。为什么使用python线程模块而不是方法和异步操作?这在大多数情况下都应该有效。