使用VS Code Python和PYQT5实现简单的按键精灵

这篇具有很好参考价值的文章主要介绍了使用VS Code Python和PYQT5实现简单的按键精灵。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

  1. 创建工程

创建工程目录,创建UI文件,创建Main Window

python是否能实现按键精灵的功能,PYQT,ui,python,pyqt,pip,Powered by 金山文档
  1. 需求整理

使用思维导图进行简单的需求整理

python是否能实现按键精灵的功能,PYQT,ui,python,pyqt,pip,Powered by 金山文档
  1. 简单设计UI

由于没怎么用过pyqt,简单排版一下,后续也可以再用Vertical Layout和Horizontal Layout进行排版优化,按设计,三个文本框进行-功能说明,-时间间隔填写,-状态说明的显示,一个按钮可以选择-删除文件,下方的大表格框用来选中并且显示录制的脚本文件名及其属性。

python是否能实现按键精灵的功能,PYQT,ui,python,pyqt,pip,Powered by 金山文档

逐一修改控件的objectname,便于代码调用,增加可读性,然后保存ui文件生成界面代码:

python是否能实现按键精灵的功能,PYQT,ui,python,pyqt,pip,Powered by 金山文档

生成了UI文件:

python是否能实现按键精灵的功能,PYQT,ui,python,pyqt,pip,Powered by 金山文档

代码如下:

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'c:\learning\python\pyqt\mouse_recorder\mouse_recorder.ui'
#
# Created by: PyQt5 UI code generator 5.15.4
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again.  Do not edit this file unless you know what you are doing.


from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(800, 400)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.doc_textBrowser = QtWidgets.QTextBrowser(self.centralwidget)
        self.doc_textBrowser.setGeometry(QtCore.QRect(40, 10, 391, 61))
        self.doc_textBrowser.setObjectName("doc_textBrowser")
        self.deleteFile_Btn = QtWidgets.QPushButton(self.centralwidget)
        self.deleteFile_Btn.setGeometry(QtCore.QRect(450, 50, 131, 21))
        self.deleteFile_Btn.setObjectName("deleteFile_Btn")
        self.file_tableWidget = QtWidgets.QTableWidget(self.centralwidget)
        self.file_tableWidget.setGeometry(QtCore.QRect(40, 90, 700, 300))
        self.file_tableWidget.setObjectName("file_tableWidget")
        self.file_tableWidget.setColumnCount(0)
        self.file_tableWidget.setRowCount(0)
        self.file_tableWidget.horizontalHeader().setCascadingSectionResizes(False)
        self.file_tableWidget.verticalHeader().setVisible(False)
        self.timeinterval_lineEdit = QtWidgets.QLineEdit(self.centralwidget)
        self.timeinterval_lineEdit.setGeometry(QtCore.QRect(460, 20, 113, 20))
        self.timeinterval_lineEdit.setObjectName("timeinterval_lineEdit")
        self.status_textEdit = QtWidgets.QTextEdit(self.centralwidget)
        self.status_textEdit.setGeometry(QtCore.QRect(600, 10, 141, 61))
        self.status_textEdit.setObjectName("status_textEdit")
        MainWindow.setCentralWidget(self.centralwidget)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "KeyHelper"))
        self.doc_textBrowser.setHtml(_translate("MainWindow", "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
"<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n"
"p, li { white-space: pre-wrap; }\n"
"</style></head><body style=\" font-family:\'SimSun\'; font-size:9pt; font-weight:400; font-style:normal;\">\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">功能说明:</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">功能1.填入时间间隔(可以是小数),按F8鼠标左键连点当前位置。</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">功能2.按F9开始鼠标键盘录制,再按F9结束录制并保存在scripts目录下。</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">功能3.勾选录制文件,按F10进行录制回放。</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">功能4.默认加载当前目录下scripts目录的脚本(其他目录目前不支持)。</p>\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">功能6.点击“删除录制文件”,可以将当前选中的文件删除。</p></body></html>"))
        self.deleteFile_Btn.setText(_translate("MainWindow", "删除录制文件"))

后续我们需要一个文件实现界面类对界面进行操作,另外实现一个功能类进行各类功能监听及实现,简单创建两个py文件:

python是否能实现按键精灵的功能,PYQT,ui,python,pyqt,pip,Powered by 金山文档
  1. 线程设计

为了界面和功能逻辑分开,需要简单设计一下多线程:

python是否能实现按键精灵的功能,PYQT,ui,python,pyqt,pip,Powered by 金山文档
  1. 代码实现

界面逻辑代码my_window.py:

import sys
import os
import time
import json
from PyQt5.QtCore import Qt, QObject, QThread, pyqtSignal
from PyQt5.QtWidgets import QApplication, QMainWindow, QCheckBox, QTableWidgetItem, QFileDialog
from Ui_mouse_recorder import *
from my_recorder import *

class MyWindow(QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        super(MyWindow, self).__init__(parent)
        self.__cur_checkbox = None
        self.__filelist = []
        self.__curfilepath = []
        self.setupUi(self)
        self.inittable()
        self.getscripts()
        self.timeinterval_lineEdit.setPlaceholderText("请输入点击间隔(秒):")
        self.deleteFile_Btn.clicked.connect(self.deletefile)
        self.recorder = MyRecorder(self)
        self.recorder.refresh.connect(self.refresh_file_list)
        self.recorder.minimized.connect(self.minimized_window)
        self.recorder.active.connect(self.active_window)
        self.recorder.savefile.connect(self.savefile)
        self.recorder.showstatus.connect(self.showstatus)

    def inittable(self):
        # set row and column
        self.file_tableWidget.setColumnCount(3)
        self.file_tableWidget.setRowCount(1)
        self.file_tableWidget.setColumnWidth(0, 50)
        self.file_tableWidget.setColumnWidth(1, 325)
        self.file_tableWidget.setColumnWidth(2, 325)
        # set data title
        self.file_tableWidget.horizontalHeader().setStyleSheet("QHeaderView::section{background:skyblue;}")
        self.file_tableWidget.setHorizontalHeaderItem(0, QTableWidgetItem("序号"))
        self.file_tableWidget.setHorizontalHeaderItem(1, QTableWidgetItem("文件名"))
        self.file_tableWidget.setHorizontalHeaderItem(2, QTableWidgetItem("修改时间"))
        self.file_tableWidget.horizontalHeader().setStretchLastSection(True)
        
        # setting
        self.file_tableWidget.setEditTriggers(QtWidgets.QAbstractItemView.EditTrigger.NoEditTriggers)


    def getscripts(self):
        scriptspath = self.get_scripts_path()
        if not os.path.exists(scriptspath):
            os.makedirs(scriptspath)
        if self.__filelist==[]: #file list is [], reinit file list
            for file in os.listdir(scriptspath):
                if file.endswith(".json"):
                    self.__filelist.append(file)
        row_num = len(self.__filelist)
        self.file_tableWidget.setRowCount(row_num)
        # set data items
        for row in range(row_num):
            # first column is checkbox
            item_checked = QCheckBox(parent=self.file_tableWidget)
            item_checked.setText(str(row + 1))
            item_checked.setCheckState(Qt.Unchecked)
            item_checked.clicked.connect(self.table_item_clicked)
            self.file_tableWidget.setCellWidget(row, 0, item_checked)
            # second column is filename
            item_name = QTableWidgetItem(self.__filelist[row])
            item_name.setTextAlignment(Qt.AlignHCenter | Qt.AlignVCenter)
            self.file_tableWidget.setItem(row, 1, item_name)
            # third column is modification time
            filepath = os.path.join(scriptspath, self.__filelist[row])
            mtime = os.stat(filepath).st_mtime
            mtime_str = time.strftime('%Y_%m_%d %H:%M:%S', time.localtime(mtime))
            item_time = QTableWidgetItem(mtime_str)
            item_time.setTextAlignment(Qt.AlignHCenter | Qt.AlignVCenter)
            self.file_tableWidget.setItem(row, 2, item_time)

    def refresh_file_list(self, file):
        #if file do not exist
        if not file in self.__filelist:  
            self.__filelist.append(file)
        self.getscripts()

    def deletefile(self):
        ix = self.file_tableWidget.indexAt(self.__cur_checkbox.pos())
        file = self.__filelist[ix.row()]
        scriptpath = self.get_scripts_path()
        filepath = scriptpath + file
        print("delete file", filepath)
        os.remove(filepath)
        self.__filelist.remove(file)
        self.getscripts()


    def get_scripts_path(self):
        #get current path
        cwdpath = os.getcwd()
        print("current path" + cwdpath)
        #create or enter scripts path
        scriptspath = cwdpath + "\scripts\\"
        print("scripts path" + scriptspath)
        return scriptspath

    # when select one check box,others should be not selected, everytime we only delete/excute one file
    def table_item_clicked(self):
        check_box = self.sender()
        ix = self.file_tableWidget.indexAt(check_box.pos())
        num = self.file_tableWidget.rowCount()
        print("check box number:", num)
        print(ix.row(), ix.column(), check_box.isChecked())
        self.__cur_checkbox = check_box
        file = self.__filelist[ix.row()]
        scriptpath = self.get_scripts_path()
        self.__curfilepath = scriptpath + file
        if check_box.isChecked() == True:
            for i in range(num):
                if i != ix.row():
                    ch = self.file_tableWidget.cellWidget(i,0)
                    ch.setCheckState(Qt.Unchecked)

    def get_current_filepath(self):
        return self.__curfilepath
    
    def minimized_window(self):
        self.setWindowState(Qt.WindowMinimized)
    
    def active_window(self):
        self.setWindowState(Qt.WindowActive)

    def savefile(self):
        path = self.get_scripts_path()
        filepath = QFileDialog.getSaveFileName(self, "保存文件", path, "json(*.json)")
        print("save file path", filepath[0])
        filename = os.path.basename(filepath[0])
        command_list = self.recorder.getcommandlist()
        self.tofile(command_list, filepath[0])
        self.refresh_file_list(filename)

    def tofile(self, commandlist, path):
        with open(path, "w") as f:
            f.write(json.dumps(commandlist))    #使用json格式写入

    def showstatus(self, str):
        self.status_textEdit.setText(str)
        

if __name__ == '__main__':
    app = QApplication(sys.argv)
    myWin = MyWindow()
    myWin.show()
    sys.exit(app.exec_())

应用逻辑代码my_recorder.py:

import os, time
import threading
import json
#import pyautogui
from datetime import datetime
from pynput import mouse, keyboard
from pynput.mouse import Button, Controller as MouseController
from pynput.keyboard import Key, Controller as KeyController, KeyCode
from PyQt5.QtWidgets import QApplication, QMainWindow, QFileDialog
from PyQt5.QtCore import QObject, QThread, pyqtSignal
from Ui_mouse_recorder import *
from my_window import *


RECORD_KEY = Key.f9
PLAY_KEY = Key.f10
CON_CLICK_KEY = Key.f8

command_list=[]

BUTTONS = {
        "Button.left": Button.left,
        "Button.right": Button.right,
        "Button.middle": Button.middle
}

class MyRecorder(QObject):
    refresh = pyqtSignal(str)
    minimized = pyqtSignal()
    active = pyqtSignal()
    savefile = pyqtSignal()
    showstatus = pyqtSignal(str)
    def __init__(self, Window=None):
        super().__init__()
        self.__window = Window
        self.__record_flag = False
        self.__conclick_flag = False
        self.__play_flag = False
        self.__key_thread = keyboard.Listener(on_press=self.on_press, on_release=self.on_release)
        self.__key_thread.start()
        self.__mouse_thread = mouse.Listener(on_click=self.on_click)
        self.__mouse_thread.start()

    def on_click(self, x, y, button, pressed):
        if self.__record_flag:
            timestr= datetime.now().strftime("%Y_%m_%d_%H_%M_%S.%f")[:-3]
            print(timestr, x, y, pressed, button)
            command_list.append((
                "mouse", #opration object
                (x, y, pressed, str(button)),
                timestr
            ))
    
    def on_press(self, key):
        if key == CON_CLICK_KEY or key == RECORD_KEY or key == PLAY_KEY:
            print("press key", key)
        else:
            if self.__record_flag:
                self.record_key(key, True) #True or False for press or release

    def on_release(self, key):
        print("release key", key)
        if key == CON_CLICK_KEY or key == RECORD_KEY or key == PLAY_KEY:
            self.handle_key(key)#do nothing when press function keys
        else:
            if self.__record_flag:
                self.record_key(key, False)

    def handle_key(self, key):
        if key == CON_CLICK_KEY:
            self.handle_conclick()
        elif key == RECORD_KEY:
            self.handle_record()
        elif key == PLAY_KEY:
            self.handle_play()
        else:
            print("error key")

    def continuous_click(self):
        interval = self.__window.timeinterval_lineEdit.text()
        print("interval", interval)
        if interval == "": #if no numbers, default to 1s
            interval = 1
        interval = float(interval)
        #self.__window.setWindowState(Qt.WindowMinimized)
        mouse = MouseController()
        while self.__conclick_flag:
            print(datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
            mouse.click(button=Button.left)
            print("continuous click key")
            time.sleep(interval)

    def handle_conclick(self):
        global mouse_click_thread
        if self.__conclick_flag:
            self.__conclick_flag = False
            mouse_click_thread.join()
            if not mouse_click_thread.is_alive():
                mouse_click_thread = None
            self.showstatus.emit("当前状态:\n鼠标左键连点结束...")
            self.active.emit()
            #self.__window.setWindowState(Qt.WindowActive)
        else:
            self.__conclick_flag = True
            #create new threading everytime
            #self.__window.setWindowState(Qt.WindowMinimized)
            mouse_click_thread = threading.Thread(target=self.continuous_click)
            mouse_click_thread.start()
            self.showstatus.emit("当前状态:\n鼠标左键连点中...")
            self.minimized.emit()

    def handle_record(self):
        print(self.__record_flag)
        if self.__record_flag:
            print("stop recording")
            self.__record_flag = False
            self.showstatus.emit("当前状态:\n鼠标键盘录制结束...")
            self.active.emit()
            self.savefile.emit()
            #self.__window.setWindowState(Qt.WindowActive)
            #get current path
            #cwdpath = os.getcwd()
            #print("current path" + cwdpath)
            #create or enter scripts path
            #scriptspath = cwdpath + "\scripts\\"
            #filename = time.strftime('%Y_%m_%d_%H_%M_%S', time.localtime(time.time())) + "_Record.json"
            #path = scriptspath + filename
            #print(path)
            #self.tofile(command_list, path)
            #self.refresh.emit(filename)
        else:
            #self.__window.setWindowState(Qt.WindowMinimized)
            self.showstatus.emit("当前状态:\n鼠标键盘录制中...")
            self.minimized.emit()
            print("start recording")
            self.__record_flag = True
            print("flag", self.__record_flag)

    def handle_play(self):
        global record_play_thread
        if self.__play_flag:
            self.__play_flag = False
            print("play flag", self.__play_flag)
            record_play_thread.join()
            if record_play_thread.is_alive():
                record_play_thread = None
            self.showstatus.emit("当前状态:\n鼠标键盘播放结束...")
            self.active.emit()
        else:
            self.__play_flag = True
            #self.__window.setWindowState(Qt.WindowMinimized)
            record_play_thread = threading.Thread(target=self.do_play)
            record_play_thread.start()
            self.showstatus.emit("当前状态:\n鼠标键盘播放中...")
            self.minimized.emit()
    
    def do_play(self):
        filepath = self.__window.get_current_filepath()
        print(filepath)
        if filepath == []:
            return
        command_read = []
        with open(filepath, encoding='utf-8-sig', errors='ignore') as f:
            command_read = json.loads(f.read())
        
        while True:
            print("do play")
            old_timestamp = 0
            timestamp = 0
            i = 0
            for command in command_read:
                print("one command start", i)
                print("oldtimestamp", old_timestamp)
                timestr = command[2]
                print("timestr", timestr)
                timestamp = datetime.strptime(timestr, "%Y_%m_%d_%H_%M_%S.%f").timestamp()
                print("timestamp", timestamp)
                if old_timestamp !=0:
                    timedelay = timestamp - old_timestamp
                    print("delay", timedelay)
                    time.sleep(timedelay)
                    if not self.__play_flag:
                        break
                old_timestamp = timestamp
                if command[0] == "mouse":
                    mouse = MouseController()
                    paser = command[1]
                    x = paser[0]
                    y = paser[1]
                    pressed = paser[2]
                    value = paser[3]
                    print("mouse play", x, y, value, pressed, timestr)
                    #pyautogui.moveTo(x,y)
                    mouse.position = (x,y)
                    if pressed:
                        mouse.press(button=BUTTONS[value])
                    else:
                        mouse.release(button=BUTTONS[value])
                elif command[0] == "keyboard":
                    keycon= KeyController()
                    paser = command[1]
                    pressed = paser[2]
                    value = paser[3]
                    if value[:3] == "Key":
                        key = eval(value, {}, {"Key": keyboard.Key})
                    else:
                        key = value
                    #value = "Key." + value.replace('\'','')
                    print(value, pressed, timestr)
                    #key = getattr(KeyCode, value)
                    if pressed:
                        keycon.pressed(key)
                    else:
                        keycon.release(key)
                    print("keyboard play", key, pressed)           
                else:
                    print("incorrect mode")
                i = i + 1
                if not self.__play_flag:
                    break
            print("self.__play_flag", self.__play_flag)
            if not self.__play_flag:
                break
            interval = self.__window.timeinterval_lineEdit.text()
            print("interval", interval)
            if interval == "": #if no numbers, default to 1s
                interval = 1
            interval = float(interval)
            time.sleep(interval)

    def record_key(self, key, pressed):
        timestr= datetime.now().strftime("%Y_%m_%d_%H_%M_%S.%f")[:-3]
        print(timestr, pressed, key)
        command_list.append((
            "keyboard", #opration object
            (-1, -1, pressed, str(key).strip("'")),
            timestr
        ))

    def getcommandlist(self):
        return command_list
  1. 打包python代码成为exe文件

首先安装pyinstaller:

pip install Pyinstaller

进入工程目录执行命令打包主函数文件:

Pyinstaller -F -w my_window.py

最终的可执行exe文件在代码目录的dist目录中,如果没有防火墙或者杀毒软件之类,双击即可使用。

PS:博主也刚开始学习python跟pyqt5,以上实现肯定有所缺陷,如发现问题请多多指正。

参考文章:

https://blog.csdn.net/sinat_33408502/article/details/121903944

https://www.freesion.com/article/2628907460/

代码传到github:

https://github.com/Sampsin/learning.git文章来源地址https://www.toymoban.com/news/detail-812039.html

到了这里,关于使用VS Code Python和PYQT5实现简单的按键精灵的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Python实现按键精灵功能

    最近一个小游戏挺火的,羊了个羊,很多程序员都通过后台破解代码让道具无限,让关卡重复第一关等等来实现通关,但技术不够,代码来凑,想着游戏还有一定的几率可以通关,无非就是要多试几把,那要不写个程序让电脑无限的自动匹配点击。 第一想法是用按键精灵,但

    2024年02月06日
    浏览(29)
  • 【python】用PyQt5教你制作简单的水果抽奖机

    水果机模拟器的介绍 制作水果机的步骤 水果机的UI设计  水果机的代码 UI内置代码   用代码对UI进行修饰  窗体属性 启动游戏   Qtime的timeout事件  窗体加载 总结  网络上对的介绍:水果机最为常见的是在街机厅中见到的,以新颖的水果作为游戏主题,融合了博彩类游戏元

    2023年04月08日
    浏览(27)
  • 关于python中Process finished with exit code -1073741819 (0xC0000005)错误,PyQt5导包错误的解决

      关于在pycharm中导入可视化程序开发框架PyQt5,PyQt6是出现的问题Process finished with exit code -1073741819 (0xC0000005)有以下尝试解决的方法。(每一种方法亲测) 1.在File-Settings-Build,Execution,Deployment-Python Debugger中去掉勾选的PyQt compatible点击确定。     2.更换python版本,作者测试了更换

    2024年02月15日
    浏览(32)
  • PyQt5按下按键选择文件并显示路径

    一、可直接运行代码 二、函数解释 fileName是文件的绝对路径,fileType是文件类型 第一个参数parent,用于指定父组件,一般是一个窗口,在这个窗口建立选择文件的对话框。这里是None。 第二个参数caption,定义这个选择文件的对话框的标题。 第三个参数dir,是对话框显示时默认

    2024年02月11日
    浏览(32)
  • 使用PyQt5设计一款简单的计算器

    目录 一、环境配置: 二、代码实现 三、主程序 四、总结         本文使用PyQt5设计一款简单的计算器,可以通过界面交互实现加减乘除的功能,希望能够给初学者一些帮助。主要涉及的知识点有类的定义与初始化、类的成员函数、pyqt5的信号与槽函数等。 具体界面如下

    2024年02月03日
    浏览(25)
  • <Python>PyQt5+ffmpeg,简单视频播放器的编写(解码器:K-lite)

    更新日志: 202211251640:第一版,基本功能:视频导入,播放、暂停、播放时间显示、音量控制 概述:本文是利用PyQt5加上ffmpeg来编写一个具备基本功能的视频播放器(播放、暂停、进度调整、音量调整、视频播放列表、文件夹导入视频等) 实现步骤设想:PyQt制作UI界面,利

    2024年02月16日
    浏览(40)
  • python、pyqt5实现人脸检测、性别和年龄预测

    摘要:这篇博文介绍基于opencv:DNN模块自带的残差网络的人脸、性别、年龄识别系统,系统程序由OpenCv, PyQt5的库实现。如图系统可通过摄像头获取实时画面并识别其中的人脸表情,也可以通过读取图片识别,本文提供完整的程序文件并详细介绍其实现过程。博文要点如下:

    2024年02月07日
    浏览(82)
  • pyqt5使用Designer实现按钮上传图片

    1、ui界面 2、ui转py代码 其中 uploadimg.py 代码如下: 3、upload_main.py主函数代码 upload_main.py 代码如下: 4、效果图

    2024年02月04日
    浏览(41)
  • Python PyQt5——QThread使用方法与代码实践

    在 GUI 程序中,如果想要让程序执行一项耗时的工作,例如下载文件、I/O 存取等,深度学习模型推理,直接在 UI 线程中进行这些操作会导致整个界面卡住,出现无响应的状态。为了避免这种情况,可以将这些耗时任务放在另一个线程中执行。在 PyQt 中,可以使用 QThread 来实现

    2024年04月27日
    浏览(24)
  • PyQt5使用QtDesigner实现多界面切换程序

    一、首先要安装QtDesigner         具体安装步骤在此不做赘述,若是有需要的小伙伴可以去找一找教程。 二、简单介绍 QtDesigner         各位伙伴安装完成打开之后的界面类似如下图(Windows版本),图片中已经对各个区域及其作用进行简单介绍,具体用法会在下面继续讲解。

    2024年02月02日
    浏览(26)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包