0

I have a small recorder application in kivy which should control screen capture activity. The recorder app should present a status line and a recording / pause button depending on the status of the recorder. The initial sequence is: Waiting (i.e. waiting for some action - press rec button) > Set Application (i.e. enduser should bring other application window to foreground by mouse click) > Recording (capture screen images from mouse click) > Pause or Stop. To trigger the capture activity, I am using pyHook to read the mouse event. However, as soon as pyHook.HookManager() is called I am loosing access to the kivy recorder application and can not control the recording process: button clicks are not captured, status line and Event ID are not updated. What am I missing here?

Attached the Python code, kv file and for convenience the image files. Thanks for your help and time in advance.

import os
import pyHook
import pythoncom

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.core.window import Window
from kivy.properties import StringProperty, NumericProperty
from kivy.clock import Clock

hm = None
recStatus = None
eventListID = 0

class hookHome(BoxLayout):

    curevent = NumericProperty()
    recpbutton = StringProperty()
    stopbutton = StringProperty()
    status = StringProperty()

    def init_recorder(self):
        global recStatus
        global eventListID
        self.recpbutton = './Record.png'
        self.stopbutton = './Stop.png'
        self.curevent = eventListID
        self.status = 'waiting'
        recStatus = 'INIT'

    def recording_pause_proc(self):
        global recStatus
        global hm
        if recStatus == 'INIT':
            self.recpbutton = './Pause-r.png'
            recStatus = 'SETAPPL'
            self.status = 'set applic.'
            Clock.schedule_once(self.proc_recorder, 0)

        elif recStatus == 'RECORD':
            self.recpbutton = './Record.png'
            recStatus = 'PAUSE'
            self.status = 'pause'
            hm.UnhookMouse()
            hm.UnhookKeyboard()

        elif recStatus == 'PAUSE':
            self.recpbutton = './Pause-r.png'
            recStatus = 'RECORD'
            self.status = 'recording'
            hm.HookMouse()
            hm.HookKeyboard()

        elif recStatus == 'SETAPPL':
            self.recpbutton = './Pause-r.png'
            recStatus = 'RECORD'
            self.status = 'recording'

    def stop_recorder(self):
        hm.UnhookMouse()
        hm.UnhookKeyboard()
        os._exit(0)

    def onMouseEvent(self, event):
        global recStatus
        if recStatus == 'SETAPPL':
            recStatus = 'RECORD'
            self.status = 'recording'

        elif recStatus == 'RECORD':
            print "Capture window..."
        return True


    def proc_recorder(self, *args):
        global hm
        hm = pyHook.HookManager()
        hm.MouseAllButtonsDown = self.onMouseEvent
        hm.HookMouse()
        pythoncom.PumpMessages()


class hooktestApp(App):

    def build(self):
        Window.clearcolor = (1,1,1,1)
        Window.size = (180, 55)
        homeWin = hookHome()
        homeWin.init_recorder()
        return homeWin

if __name__ == '__main__':
    hooktestApp().run()

and the kv file:

<hookHome>:

    orientation: "vertical"
    BoxLayout:
        orientation: 'vertical'
        BoxLayout:
            orientation: 'horizontal'
            height: "15dp"
            size_hint_y: None
            Label:
                canvas.before:
                    Color:
                        rgb:  0.7,0.9,1
                    Rectangle:
                        pos: self.pos
                        size: self.size
                size_hint: 0.6,1
                text: "Recorder"
                text_size: self.width -10, self.height
                halign: 'left'
                valign: 'middle'
                font_size: 12
                color: .3,.3,.3,1

            Label:
                canvas.before:
                    Color:
                        rgb:  0.7,0.9,1
                    Rectangle:
                        pos: self.pos
                        size: self.size
                size_hint: 0.4,1
                text: root.status
                text_size: self.width-10, self.height
                halign: 'right'
                valign: 'middle'
                font_size: 12
                color: .3,.3,.3,1

    BoxLayout:
        height: "40dp"
        size_hint_y: None
        orientation: "horizontal"

        BoxLayout:
            orientation: "vertical"
            size_hint: 0.33,1
            Label:
                canvas.before:
                    Color:
                        rgb: 0,.24,.42
                    Rectangle:
                        pos: self.pos
                        size: self.size
                size_hint: 1,0.65
                text: str(root.curevent)
                size: self.texture_size
                halign: 'center'
                valign: 'middle'
                font_size: 16
                color: 1,1,1,1
            Label:
                canvas.before:
                    Color:
                        rgb: 0,.24,.42
                    Rectangle:
                        pos: self.pos
                        size: self.size
                size_hint: 1,0.35
                #text: root.curevent
                text: 'Event'
                size: self.texture_size
                halign: 'center'
                valign: 'middle'
                font_size: 14
                color: 1,1,1,1

        Button:
            size_hint: 0.33,1
            background_normal: './dblButton.png'
            background_down: './lblButton.png'
            on_press: root.recording_pause_proc()
            Image:
                source: root.recpbutton
                center_x: self.parent.center_x
                center_y: self.parent.center_y

        Button:
            size_hint: 0.33,1
            background_normal: './dblButton.png'
            background_down: './lblButton.png'
            on_press: root.stop_recorder()
            Image:
                source: root.stopbutton
                center_x: self.parent.center_x
                center_y: self.parent.center_y

dblButton.png

lblButton.png

Record.png

Stop.png

Pause-r.png

Bill Bridge
  • 821
  • 1
  • 9
  • 30

1 Answers1

0

Just for the records, it may not be a good idea to mix up pumpmessages and pyhook with the Kivy architecture. So I have separated the actual recording functionality into a separate process where status processing between the kivy app (recorder control through the kivy buttons) and the recorder is communicated through a bi-directional queue.

Bill Bridge
  • 821
  • 1
  • 9
  • 30