根据用户输入动态更改标签文本

2022-02-23 00:00:00 python python-3.x pyqt5 user-input

问题描述

我正在尝试创建一个包含2个python文件的应用程序,第一个文件读取用户输入(从python shell读取,或者通过pynput-keyboard之类的模块直接从键盘读取),并将其存储在一个变量中(在按空格键之后)。然后,它将原始字符串和新的转换字符串发送到GUI的标签。

第二个创建具有两个标签和两个按钮的GUI,并获取从第一个文件传递的变量,并基于此变量更改标签(这些按钮用于在数据库的后续步骤中插入数据)。

我已经创建了读取输入的gui和python脚本,但我正在努力将此变量传递给第二个脚本,并动态更改标签。

请参阅上面的代码示例。

read_user_input.py

import keyboard
import gui

def transform_string(string):
    if len(string)>0:
        return string[0:len(string)-1]
    else:
        return "0"

def logging_function():
    string = ""

    while(True):
        event = keyboard.read_event()
        if (str(event)[-5:-1] == "down"):
            key_pressed = ((str(event).rsplit(' ', 1))[0])[14:]

            if (key_pressed == "space"):
                """PASS THIS string AND transform_string TO OUR GUI's LABELS"""
                print("Pass to gui's labels")
            else:
                string = string + key_pressed




logging_function()

gui.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>Hook</class>
 <widget class="QMainWindow" name="Hook">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>237</width>
    <height>120</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Hook</string>
  </property>
  <property name="windowIcon">
   <iconset>
    <normaloff>10-03-2020 thesis_01/keyboard.ico</normaloff>10-03-2020 thesis_01/keyboard.ico</iconset>
  </property>
  <widget class="QWidget" name="centralwidget">
   <widget class="QLabel" name="label">
    <property name="geometry">
     <rect>
      <x>10</x>
      <y>0</y>
      <width>131</width>
      <height>31</height>
     </rect>
    </property>
    <property name="text">
     <string>Label1</string>
    </property>
   </widget>
   <widget class="QLabel" name="label_2">
    <property name="geometry">
     <rect>
      <x>10</x>
      <y>40</y>
      <width>131</width>
      <height>31</height>
     </rect>
    </property>
    <property name="mouseTracking">
     <bool>false</bool>
    </property>
    <property name="text">
     <string>Label2</string>
    </property>
   </widget>
   <widget class="QPushButton" name="pushButton">
    <property name="geometry">
     <rect>
      <x>160</x>
      <y>0</y>
      <width>61</width>
      <height>31</height>
     </rect>
    </property>
    <property name="text">
     <string>B1</string>
    </property>
   </widget>
   <widget class="QPushButton" name="pushButton_2">
    <property name="geometry">
     <rect>
      <x>160</x>
      <y>42</y>
      <width>61</width>
      <height>31</height>
     </rect>
    </property>
    <property name="text">
     <string>B2</string>
    </property>
   </widget>
  </widget>
  <widget class="QMenuBar" name="menubar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>237</width>
     <height>21</height>
    </rect>
   </property>
   <widget class="QMenu" name="menuHook">
    <property name="title">
     <string>Hook</string>
    </property>
   </widget>
   <widget class="QMenu" name="menuHelp">
    <property name="title">
     <string>Help</string>
    </property>
   </widget>
   <addaction name="menuHook"/>
   <addaction name="menuHelp"/>
  </widget>
  <widget class="QStatusBar" name="statusbar"/>
 </widget>
 <resources/>
 <connections/>
</ui>

gui.py

from PyQt5 import QtWidgets, uic
import sys

class Ui(QtWidgets.QMainWindow):
    def __init__(self):
        super(Ui, self).__init__() # Call the inherited classes __init__ method
        uic.loadUi('untitled.ui', self) # Load the .ui file
        self.show() # Show the GUI

app = QtWidgets.QApplication(sys.argv) # Create an instance of QtWidgets.QApplication
window = Ui() # Create an instance of our class
app.exec_() # Start the application

UI窗口如下所示:


解决方案

您要做的就是使用pynput侦听器并分析密钥代码,然后根据此构建单词并通过信号将其发送到图形用户界面,图形用户界面根据其自身的逻辑将其添加到QLabel:

read_user_input.py

from pynput.keyboard import Key, Listener

from PyQt5 import QtCore


class KeyMonitor(QtCore.QObject):
    wordPressed = QtCore.pyqtSignal(str)

    def __init__(self, parent=None):
        super().__init__(parent)
        self.listener = Listener(on_release=self.on_release)
        self.word = ""

    def on_release(self, key):
        if hasattr(key, "char"):
            self.word += key.char
        if key == Key.space:
            self.wordPressed.emit(self.word)
            self.word = ""

    def stop_monitoring(self):
        self.listener.stop()

    def start_monitoring(self):
        self.listener.start()

gui.py

from itertools import cycle
import sys

from PyQt5 import QtCore, QtWidgets, uic

from read_user_input import KeyMonitor


class Ui(QtWidgets.QMainWindow):
    def __init__(self):
        super(Ui, self).__init__()
        uic.loadUi("untitled.ui", self)
        self.show()

        self.labels = cycle([self.label, self.label_2])

    @QtCore.pyqtSlot(str)
    def on_word_pressed(self, word):
        le = next(self.labels)
        le.setText(word)


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    window = Ui()
    monitor = KeyMonitor()
    monitor.wordPressed.connect(window.on_word_pressed)
    monitor.start_monitoring()
    sys.exit(app.exec_())

更新:

如果要使用键盘库,则必须使用以下各项:

read_user_input.py

import threading

import keyboard

from PyQt5 import QtCore


class KeyMonitor(QtCore.QObject):
    wordPressed = QtCore.pyqtSignal(str)

    def __init__(self, parent=None):
        super().__init__(parent)
        self.word = ""

        self.listener = threading.Thread(target=self._task, daemon=True)

    def _task(self):
        while True:
            event = keyboard.read_event()
            if event.event_type == keyboard.KEY_DOWN:
                if event.name == "space":
                    self.wordPressed.emit(self.word)
                    self.word = ""
                elif len(event.name) == 1:
                    self.word += event.name

    def start_monitoring(self):
        self.listener.start()

更新:

修改数据的逻辑是一项琐碎的任务,它包括汇聚"word"和生成新字符串:

import sys

from PyQt5 import QtCore, QtWidgets, uic

from read_user_input import KeyMonitor


class Ui(QtWidgets.QMainWindow):
    def __init__(self):
        super(Ui, self).__init__()
        uic.loadUi("untitled.ui", self)
        self.show()

    @QtCore.pyqtSlot(str)
    def on_word_pressed(self, word):
        try:
            x = int(word)
        except ValueError:
            print("You must enter a whole number")
        else:
            self.label.setText("{}".format(x + 2))
            self.label_2.setText("Changed {}".format(x - 2))


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    window = Ui()
    monitor = KeyMonitor()
    monitor.wordPressed.connect(window.on_word_pressed)
    monitor.start_monitoring()
    sys.exit(app.exec_())

相关文章