main
Brett 2025-06-19 13:16:21 -04:00
parent 1e064c3371
commit 4355f15f85
3 changed files with 171 additions and 42 deletions

View File

@ -1,14 +1,22 @@
import uinput import uinput
import time import time
import asyncio
import evdev import evdev
import queue
from evdev import InputDevice, categorize, ecodes from evdev import InputDevice, categorize, ecodes
from evdev import UInput, ecodes as e from evdev import UInput, ecodes as e
import threading import threading
from threading import Thread from threading import Thread
import sys import sys
from PyQt5 import QtCore, QtWidgets, QtGui from PyQt5 import QtCore, QtWidgets, QtGui
from PyQt5.QtGui import QPalette, QColor
import signal
device_path = '/dev/input/event5' # You can find this with `evtest` event_queue = queue.Queue()
global app, overlay
device_paths = [('/dev/input/event1', {"KEY_F20", "KEY_F24"}), ('/dev/input/event22', {}), ('/dev/input/event5', {})]
key_events = [ key_events = [
uinput.KEY_A, uinput.KEY_B, uinput.KEY_C, uinput.KEY_D, uinput.KEY_E, uinput.KEY_A, uinput.KEY_B, uinput.KEY_C, uinput.KEY_D, uinput.KEY_E,
@ -16,7 +24,8 @@ key_events = [
uinput.KEY_K, uinput.KEY_L, uinput.KEY_M, uinput.KEY_N, uinput.KEY_O, uinput.KEY_K, uinput.KEY_L, uinput.KEY_M, uinput.KEY_N, uinput.KEY_O,
uinput.KEY_P, uinput.KEY_Q, uinput.KEY_R, uinput.KEY_S, uinput.KEY_T, uinput.KEY_P, uinput.KEY_Q, uinput.KEY_R, uinput.KEY_S, uinput.KEY_T,
uinput.KEY_U, uinput.KEY_V, uinput.KEY_W, uinput.KEY_X, uinput.KEY_Y, uinput.KEY_U, uinput.KEY_V, uinput.KEY_W, uinput.KEY_X, uinput.KEY_Y,
uinput.KEY_Z, uinput.KEY_Z, uinput.KEY_ESC, uinput.KEY_F20, uinput.KEY_F21, uinput.KEY_F22,
uinput.KEY_F23, uinput.KEY_F24,
uinput.KEY_ENTER, uinput.KEY_ENTER,
uinput.KEY_COMMA, uinput.KEY_COMMA,
@ -42,8 +51,6 @@ def left_click():
mouse.syn() mouse.syn()
def place_tower(): def place_tower():
keyboard.emit_click(uinput.KEY_Z)
time.sleep(0.05)
left_click() left_click()
time.sleep(0.05) time.sleep(0.05)
mouse.write(e.EV_REL, e.REL_Y, -10) mouse.write(e.EV_REL, e.REL_Y, -10)
@ -52,60 +59,128 @@ def place_tower():
left_click() left_click()
time.sleep(0.1) time.sleep(0.1)
def upgrade_tower(): def upgrade_top(amount = 1):
for i in range(2): for i in range(amount):
keyboard.emit_click(uinput.KEY_COMMA)
time.sleep(0.05)
def upgrade_middle(amount = 1):
for i in range(amount):
keyboard.emit_click(uinput.KEY_DOT) keyboard.emit_click(uinput.KEY_DOT)
time.sleep(0.05) time.sleep(0.05)
for i in range(2):
def upgrade_bottom(amount = 1):
for i in range(amount):
keyboard.emit_click(uinput.KEY_SLASH) keyboard.emit_click(uinput.KEY_SLASH)
time.sleep(0.05) time.sleep(0.05)
def listen_for_keypress(): def upgrade_tower():
dev = InputDevice(device_path) # for i in range(0):
print(f"Listening on {dev.name} ({device_path})") # keyboard.emit_click(uinput.KEY_DOT)
# time.sleep(0.05)
for i in range(3):
keyboard.emit_click(uinput.KEY_SLASH)
time.sleep(0.05)
keyboard.emit_click(uinput.KEY_ESC)
time.sleep(0.05)
keyboard.emit_click(uinput.KEY_C)
time.sleep(0.05)
for event in dev.read_loop(): async def listen_for_keypress(path, keys):
dev = InputDevice(path)
print(f"Listening on {dev.name} ({path})")
async for event in dev.async_read_loop():
if event.type == ecodes.EV_KEY: if event.type == ecodes.EV_KEY:
key_event = categorize(event) key_event = categorize(event)
if key_event.keycode == 'KEY_F9' and key_event.keystate == 0: if key_event.keycode in keys and key_event.keystate == 0:
place_tower() event_queue.put((dev.name, key_event.keycode))
upgrade_tower()
class Overlay(QtWidgets.QWidget): class Overlay(QtWidgets.QWidget):
def __init__(self): def __init__(self):
super().__init__() super().__init__()
# self.setAttribute(QtCore.Qt.WA_TranslucentBackground, True)
self.setAttribute(QtCore.Qt.WA_TransparentForMouseEvents, True)
# self.setAttribute(QtCore.Qt.WA_NoSystemBackground, True)
self.setWindowFlags( self.setWindowFlags(
QtCore.Qt.WindowStaysOnTopHint | QtCore.Qt.WindowStaysOnTopHint |
QtCore.Qt.FramelessWindowHint | QtCore.Qt.FramelessWindowHint |
QtCore.Qt.Tool # Makes window not appear in taskbar QtCore.Qt.Tool
) )
self.setAttribute(QtCore.Qt.WA_TranslucentBackground) self.setStyleSheet("background-color: #788178;")
self.setAttribute(QtCore.Qt.WA_TransparentForMouseEvents) # Click-through
self.label = QtWidgets.QLabel("Mode: 1", self) self.label = QtWidgets.QLabel("Mode: 1", self)
self.label.setStyleSheet("color: white; font-size: 24px; background: rgba(0,0,0,0.5); padding: 10px;") self.label.setStyleSheet("color: white; font-size: 12px; padding: 4px;")
self.label.move(50, 50) self.label.move(50, 50)
self.resize(200, 100) layout = QtWidgets.QVBoxLayout(self)
layout.setContentsMargins(2, 2, 2, 2) # Very small margins
layout.addWidget(self.label)
self.setLayout(layout)
self.adjustSize()
def update_mode(self, mode_num): # self.resize(200, 100)
self.move(0, 0)
# def paintEvent(self, event):
# painter = QtGui.QPainter(self)
# painter.setOpacity(0.1)
# painter.setBrush(QtCore.Qt.white)
# painter.setPen(QtGui.QPen(QtCore.Qt.white))
# painter.drawRect(self.rect())
# super().paintEvent(event)
def update_mode(self, mode_num: int):
self.label.setText(f"Mode: {mode_num}") self.label.setText(f"Mode: {mode_num}")
async def main():
tasks = [asyncio.create_task(listen_for_keypress(tpl[0], tpl[1])) for tpl in device_paths]
await asyncio.gather(*tasks)
def start_async():
asyncio.run(main())
def qt5():
global app, overlay
app = QtWidgets.QApplication([])
overlay = Overlay()
overlay.show()
def update_loop():
mode = 1
while True:
time.sleep(2)
mode = (mode % 3) + 1
# QtCore.QMetaObject.invokeMethod(overlay, "update_mode", QtCore.Qt.QueuedConnection, QtCore.Q_ARG(int, mode))
Thread(target=update_loop, daemon=True).start()
app.exec()
def command_processor():
while True:
try:
device_name, key_event = event_queue.get(timeout=1)
print(f"Processing event from {device_name}: {key_event}")
if key_event == "KEY_F24":
global app, overlay
app.quit()
sys.exit(0)
except queue.Empty:
continue
except Exception as e:
print(f"Error processing queue item: {e}")
if __name__ == "__main__": if __name__ == "__main__":
global app, overlay
try: try:
app = QtWidgets.QApplication(sys.argv) Thread(target=command_processor, daemon=True).start()
overlay = Overlay() Thread(target=start_async, daemon=True).start()
overlay.show() qt5()
def update_loop():
mode = 1
while True:
time.sleep(2)
mode = (mode % 3) + 1
QtCore.QMetaObject.invokeMethod(overlay, "update_mode", QtCore.Qt.QueuedConnection, QtCore.Q_ARG(int, mode))
Thread(target=update_loop, daemon=True).start()
# listen_for_keypress()
except KeyboardInterrupt: except KeyboardInterrupt:
print("Goodbye!") print("Goodbye!")
sys.exit(app.exec_()) app.quit()
sys.exit(0)
# sys.exit(app.exec_())

View File

@ -1,13 +1,31 @@
let let
pkgs = import <nixpkgs> {}; pkgs = import <nixpkgs> {};
in pkgs.mkShell { in pkgs.mkShell {
packages = [ nativeBuildInputs = with pkgs; [ qt5.qttools.dev python3Packages.autopep8 python3Packages.flake8 ];
pkgs.git propagatedBuildInputs = with pkgs; [
(pkgs.python3.withPackages (python-pkgs: [ (python3.withPackages (ps: with ps; [
python-pkgs.requests pyqt5
python-pkgs.python-uinput evdev
python-pkgs.evdev python-uinput
python-pkgs.pyqt5 ]))
]))
]; ];
packages = with pkgs; [
git
(python3.withPackages (python-pkgs: with python-pkgs; [
requests
python-uinput
evdev
pyqt5
]))
python3Packages.pyqt5
python3Packages.pip
libsForQt5.qt5.qtbase
libsForQt5.qt5.qtx11extras
qt5.qtbase
qt5.wrapQtAppsHook
qt5.qtx11extras
];
QT_QPA_PLATFORM_PLUGIN_PATH="${pkgs.qt5.qtbase.bin}/lib/qt-${pkgs.qt5.qtbase.version}/plugins";
} }

36
qt_test.py Normal file
View File

@ -0,0 +1,36 @@
from PyQt5 import QtWidgets, QtCore, QtGui
import sys
class TransparentScene(QtWidgets.QGraphicsScene):
def __init__(self):
super().__init__()
text = self.addText("Mode: 1")
text.setDefaultTextColor(QtGui.QColor("white"))
# Add a semi-transparent background rect
rect = self.addRect(text.boundingRect().adjusted(-10, -10, 10, 10),
QtGui.QPen(QtCore.Qt.NoPen),
QtGui.QBrush(QtGui.QColor(0, 0, 0, 128)))
rect.setZValue(-1) # Put behind text
class TransparentView(QtWidgets.QGraphicsView):
def __init__(self):
super().__init__()
scene = TransparentScene()
self.setScene(scene)
self.setWindowFlags(QtCore.Qt.FramelessWindowHint | QtCore.Qt.WindowStaysOnTopHint)
self.setAttribute(QtCore.Qt.WA_TranslucentBackground)
self.setStyleSheet("background: transparent;")
self.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
self.setRenderHint(QtGui.QPainter.Antialiasing)
self.setFrameShape(QtWidgets.QFrame.NoFrame)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
view = TransparentView()
view.resize(200, 100)
view.show()
sys.exit(app.exec_())