我正在制作一个实用程序,可以轻松控制笔记本电脑平板电脑设备的使用模式(即,便于在笔记本电脑模式,手写笔写入模式等之间切换)。我正在尝试将Python threading用于持续监视循环中特定状态的进程,如果该状态发生更改,则会执行某些操作。此监视与PyQt GUI同时运行,但GUI永远不会启动,我不确定原因。我会重视一些指导。
在代码中,方法stylusProximityControl
正在进行线程化。代码如下:
import os
import sys
import subprocess
import threading
import time
from PyQt4 import QtGui
import logging
# logging
logger = logging.getLogger(__name__)
logging.basicConfig()
logger.level = logging.INFO
class interface(QtGui.QWidget):
def __init__(self):
super(interface, self).__init__()
logger.info("running spin")
# engage stylus proximity control
self.stylusProximityControlOn()
# create buttons
buttonsList = []
# button: tablet mode
buttonModeTablet = QtGui.QPushButton('tablet mode', self)
buttonModeTablet.clicked.connect(self.engageModeTablet)
buttonsList.append(buttonModeTablet)
# button: laptop mode
buttonModeLaptop = QtGui.QPushButton('laptop mode', self)
buttonModeLaptop.clicked.connect(self.engageModeLaptop)
buttonsList.append(buttonModeLaptop)
# button: left
buttonLeft = QtGui.QPushButton('left', self)
buttonLeft.clicked.connect(self.engageLeft)
buttonsList.append(buttonLeft)
# button: right
buttonRight = QtGui.QPushButton('right', self)
buttonRight.clicked.connect(self.engageRight)
buttonsList.append(buttonRight)
# button: inverted
buttonInverted = QtGui.QPushButton('inverted', self)
buttonInverted.clicked.connect(self.engageInverted)
buttonsList.append(buttonInverted)
# button: normal
buttonNormal = QtGui.QPushButton('normal', self)
buttonNormal.clicked.connect(self.engageNormal)
buttonsList.append(buttonNormal)
# button: touchscreen on
buttonTouchscreenOn = QtGui.QPushButton('touchscreen on', self)
buttonTouchscreenOn.clicked.connect(self.engageTouchscreenOn)
buttonsList.append(buttonTouchscreenOn)
# button: touchscreen off
buttonTouchscreenOff = QtGui.QPushButton('touchscreen off', self)
buttonTouchscreenOff.clicked.connect(self.engageTouchscreenOff)
buttonsList.append(buttonTouchscreenOff)
# button: touchpad on
buttonTouchpadOn = QtGui.QPushButton('touchpad on', self)
buttonTouchpadOn.clicked.connect(self.engageTouchpadOn)
buttonsList.append(buttonTouchpadOn)
# button: touchpad off
buttonTouchpadOff = QtGui.QPushButton('touchpad off', self)
buttonTouchpadOff.clicked.connect(self.engageTouchpadOff)
buttonsList.append(buttonTouchpadOff)
# button: nipple on
buttonNippleOn = QtGui.QPushButton('nipple on', self)
buttonNippleOn.clicked.connect(self.engageNippleOn)
buttonsList.append(buttonNippleOn)
# button: nipple off
buttonNippleOff = QtGui.QPushButton('nipple off', self)
buttonNippleOff.clicked.connect(self.engageNippleOff)
buttonsList.append(buttonNippleOff)
# button: stylus proximity on
buttonStylusProximityControlOn = QtGui.QPushButton('stylus proximity on', self)
buttonStylusProximityControlOn.clicked.connect(self.engageStylusProximityControlOn)
buttonsList.append(buttonStylusProximityControlOn)
# button: stylus proximity off
buttonStylusProximityControlOff = QtGui.QPushButton('stylus proximity off', self)
buttonStylusProximityControlOff.clicked.connect(self.engageStylusProximityControlOff)
buttonsList.append(buttonStylusProximityControlOff)
# set button dimensions
buttonsWidth=150
buttonsHeight=60
for button in buttonsList:
button.setFixedSize(buttonsWidth, buttonsHeight)
# set layout
vbox = QtGui.QVBoxLayout()
vbox.addStretch(1)
for button in buttonsList:
vbox.addWidget(button)
vbox.addStretch(1)
self.setLayout(vbox)
# window
self.setGeometry(200, 200, 150, 100)
self.setWindowTitle('spin')
self.show()
def displayLeft(self):
logger.info("changing display to left")
os.system('xrandr -o left')
def displayRight(self):
logger.info("changing display to right")
os.system('xrandr -o right')
def displayInverted(self):
logger.info("changing display to inverted")
os.system('xrandr -o inverted')
def displayNormal(self):
logger.info("changing display to normal")
os.system('xrandr -o normal')
def touchscreenLeft(self):
logger.info("changing touchscreen to left")
os.system('xinput set-prop "ELAN Touchscreen" "Coordinate Transformation Matrix" 0 -1 1 1 0 0 0 0 1')
def touchscreenRight(self):
logger.info("changing touchscreen to right")
os.system('xinput set-prop "ELAN Touchscreen" "Coordinate Transformation Matrix" 0 1 0 -1 0 1 0 0 1')
def touchscreenInverted(self):
logger.info("changing touchscreen to inverted")
os.system('xinput set-prop "ELAN Touchscreen" "Coordinate Transformation Matrix" -1 0 1 0 -1 1 0 0 1')
def touchscreenNormal(self):
logger.info("changing touchscreen to normal")
os.system('xinput set-prop "ELAN Touchscreen" "Coordinate Transformation Matrix" 1 0 0 0 1 0 0 0 1')
def touchscreenOn(self):
logger.info("changing touchscreen to on")
os.system('xinput enable "ELAN Touchscreen"')
def touchscreenOff(self):
logger.info("changing touchscreen to off")
os.system('xinput disable "ELAN Touchscreen"')
def touchpadOn(self):
logger.info("changing touchpad to on")
os.system('xinput enable "SynPS/2 Synaptics TouchPad"')
def touchpadOff(self):
logger.info("changing touchpad to off")
os.system('xinput disable "SynPS/2 Synaptics TouchPad"')
def nippleOn(self):
logger.info("changing nipple to on")
os.system('xinput enable "TPPS/2 IBM TrackPoint"')
def nippleOff(self):
logger.info("changing nipple to off")
os.system('xinput disable "TPPS/2 IBM TrackPoint"')
def stylusProximityControl(self):
previousProximityStatus = None
while True:
proximityCommand = 'xinput query-state "Wacom ISDv4 EC Pen stylus" | grep Proximity | cut -d " " -f3 | cut -d "=" -f2'
proximityStatus = subprocess.check_output(proximityCommand, shell=True).lower().rstrip()
if (proximityStatus == "out") and (previousProximityStatus != "out"):
logger.info("stylus inactive")
self.touchscreenOn()
elif (proximityStatus == "in") and (previousProximityStatus != "in"):
logger.info("stylus active")
self.touchscreenOff()
previousProximityStatus = proximityStatus
time.sleep(0.25)
def stylusProximityControlOn(self):
logger.info("changing stylus proximity control to on")
self.thread1=threading.Thread(target=self.stylusProximityControl()).start()
def stylusProximityControlOff(self):
logger.info("changing stylus proximity control to off")
self.thread1.join()
def engageModeTablet(self):
logger.info("engaging mode tablet")
self.displayLeft()
self.touchscreenLeft()
self.touchscreenOff()
self.touchpadOff()
self.nippleOff()
def engageModeLaptop(self):
logger.info("engaging mode laptop")
self.displayNormal()
self.touchscreenNormal()
self.touchscreenOn()
self.touchpadOn()
self.nippleOn()
def engageLeft(self):
logger.info("engaging mode left")
self.displayLeft()
self.touchscreenLeft()
def engageRight(self):
logger.info("engaging mode right")
self.displayRight()
self.touchscreenRight()
def engageInverted(self):
logger.info("engaging mode inverted")
self.displayInverted()
self.touchscreenInverted()
def engageNormal(self):
logger.info("engaging mode normal")
self.displayNormal()
self.touchscreenNormal()
def engageTouchscreenOn(self):
self.touchscreenOn()
def engageTouchscreenOff(self):
self.touchscreenOff()
def engageTouchpadOn(self):
self.touchpadOn()
def engageTouchpadOff(self):
self.touchpadOff()
def engageNippleOn(self):
self.nippleOn()
def engageNippleOff(self):
self.nippleOff()
def engageStylusProximityControlOn(self):
self.stylusProximityControlOn()
def engageStylusProximityControlOff(self):
self.stylusProximityControlOff()
def main():
application = QtGui.QApplication(sys.argv)
interface1 = interface()
sys.exit(application.exec_())
if __name__ == '__main__':
main()
编辑:three_pineapples highlighted代码中出错。此错误已得到解决,代码已更新。
答案 0 :(得分:1)
好的,终于找到了运行代码的时间。简单的错误(你会踢自己!)
您需要更改行
self.thread1=threading.Thread(target=self.stylusProximityControl()).start()
到
self.thread1=threading.Thread(target=self.stylusProximityControl).start()
请注意stylusProximityControl
后删除括号。您有效地要求您的方法stylusProximityControl
运行并返回一个方法,以作为threading.Thread
的目标。当然,你的方法中有一个while True
,所以没有返回任何函数来调用threading.Thread
来在新线程中启动。希望这对你有意义!
这会让你超越你的直接问题,虽然你需要考虑使用thread.join
(我没有看到线程会加入,因为循环永远不会停止)。您可能希望while
循环仅在某个布尔值为True时循环,以便在程序退出后它可以清理子进程并退出循环。
无论如何,祝你好运,我希望你把开发放在网上(bitbucket或类似),因为它看起来很有用!
答案 1 :(得分:0)
我通过使用multiprocessing来推进解决方案。
我做了以下更改:
import threading
from multiprocessing import Process
self.thread1 = threading.Thread(target=self.stylusProximityControl()).start()
self.process1 = Process(target=self.stylusProximityControl().start()
self.thread1.join()
self.process1.join()
我现在的问题是当选择窗口上的“X”时,接近控制的多处理过程结束。这可能需要执行方法stylusProximityControlOff()
并可能修改方法。