【实操日记】使用 PyQt5 设计下载远程服务器日志文件程序
最近通过 PyQt5 设计了一个下载服务器指定日期日志文件的程序,里面有些有意思的技术点,现在做一些分享。
PyQt5 是一套 Python 绑定 Digia Qt5 应用的框架,是最强大的 GUI 库之一,使用 PyQt5 我们能够很容易的开发桌面应用,接下来我们将用它来开发一个下载服务器日志文件的小程序。
前期准备
软件
- QT5 Python 模块
- PyQt5==5.15.7
- paramiko==2.9.2 PyCharm 添加扩展工具 PyUIC PyUIC 扩展用于将使用 Qt Designer 生成的 ui 文件转成 py 文件,可以在 PyCharm 中通过 Preferences-Tools-External Tools 进行配置,截图如下:
Program:/Users/macbookpro/workspace/projects/DownloadServerLog/venv/bin/python3.9 Arguments:-m PyQt5.uic.pyuic $FileName$ -o $FileNameWithoutExtension$.py Working directory:/Users/macbookpro/workspace/projects/DownloadServerLog/ui
实操步骤
1. 创建项目
创建 DownloadServerLog 项目,设计程序结构如下:
DownloadServerLog ├── app │ ├── downloadlog.py │ └── downloadlog_qtui.py ├── main.py └── ui │ └── downloadlog_qtui.ui ├── .env
main.py 作为程序入口文件,.env 存放环境变量,ui 存放使用 Qt Designer 设计界面导出的源码文件,app 存放下载程序文件。
2.使用 QtDesigner 设计界面
Qt Designer 使用起来非常简单,可以通过“拖拉拽”的形式生成 UI 界面(文档:https://doc.qt.io/qtcreator/creator-using-qt-designer.html),设计界面如下:
这个程序功能一目了然,左侧几个输入框用于输入必要的信息,右侧一个展示框用于展示程序实时日志。界面设计好后可以将其保存至项目 DownloadServerLog 下的 ui 目录下 downloadlog_qtui.ui,供后续使用。
3. 使用 ui 生成对应的 py 文件
使用 PyCharm 打开项目,在 downloadlog_qtui.ui 文件上右键,选择 External Tools 使用 PyUIC 根据 ui 文件生成对应的 py 文件 downloadlog_qtui.py,将文件存放至 app 目录。
4. 新建 main.py 作为程序入口
在项目根目录下创建 main.py 文件:
import sys from PyQt5 import QtCore from PyQt5.QtCore import QObject, pyqtSignal from PyQt5.QtWidgets import QApplication, QMainWindow from threading import Thread from app.downloadlog_qtui import Ui_Dialog from app.downloadlog import DownloadLog class CommunicateSignal(QObject): text_print = pyqtSignal(str) # MyWindow 是主窗口程序,继承自 PyQt5.QtWidgets.QMainWindow # 和通过 ui 文件生成的 downloadlog_qtui.py 中的 Ui_Dialog 类 class MyWindow(QMainWindow, Ui_Dialog): def __init__(self, parent=None): super().__init__(parent) self.setupUi(self) self.btn_download.clicked.connect(self.click_download) # 自定义信号处理函数 self.comm_signal = CommunicateSignal() self.comm_signal.text_print.connect(self.show_text) self.set_window_init_data() def set_window_init_data(self): """设置程序窗体初始值""" # 从 .env 读取环境变量 result_dict = dict() with open('.env', 'r', encoding='utf-8') as f: for line in f.readlines(): key = line.split('=')[0].strip() value = line.split('=')[-1].strip() result_dict[key] = value # 设置输入框值 _translate = QtCore.QCoreApplication.translate self.host.setText(_translate("Dialog", result_dict.get("HOST", ''))) self.port.setText(_translate("Dialog", result_dict.get("PORT", '22'))) self.username.setText(_translate("Dialog", result_dict.get("USERNAME", 'root'))) self.password.setText(_translate("Dialog", result_dict.get("PASSWORD", ''))) self.directory.setPlainText(_translate("Dialog", result_dict.get("DIRECTORY", ''))) self.startTime.setDate(QtCore.QDate.currentDate()) self.endTime.setDate(QtCore.QDate.currentDate()) def get_window_input_value(self): """获取程序各「输入框」组件值""" return { "host": self.host.text(), "port": self.port.text(), "username": self.username.text(), "password": self.password.text(), "directory": self.directory.toPlainText(), "start_time": self.startTime.date().toString("yyyy-MM-dd"), "end_time": self.endTime.date().toString("yyyy-MM-dd"), "suffix": ".log", } def show_text(self, text): """将文本内容追加到程序「展示框」""" self.textBrowser.append(text) def click_download(self): """处理点击「下载」按钮事件""" params = self.get_window_input_value() def run(): res = DownloadLog(conn_type='ssh', comm_signal=self.comm_signal, **params) res.main() t = Thread(target=run) t.start() if __name__ == '__main__': app = QApplication(sys.argv) myWin = MyWindow() myWin.show() sys.exit(app.exec_())
MyWindow 作为主窗口程序,程序初始化时会将 self.click_download 方法注册到 下载 按钮的点击事件,并自动调用 self.set_window_init_data 方法来设置输入框初始值。
5. 下载
下载日志程序 DownloadLog 定义在 app/downloadlog.py 中,远程下载文件主要步骤有两步:
通过 SSH 登录远程服务器
通过 FTP 进行文件下载
这里采用 paramiko 来实现远程下载功能,paramiko 是一个纯 Python 库,它实现了 SSHv2 协议,提供了 SSH 和 FTP 的能力。
核心代码如下,读者可以根据自己的需求实现 DownloadLog:
class DownloadLog(object): def __init__(self, **kwargs): """初始化一些参数""" ... def main(self): # 获取 Transport 实例 tran = paramiko.Transport((self.host, int(self.port))) # 连接 SSH 服务端 tran.connect(username=self.username, password=self.password) # 创建 SFTP 实例 self.sftp = paramiko.SFTPClient.from_transport(tran) # 下载文件 # :param str remotepath: the remote file to copy # :param str localpath: the destination path on the local host self.sftp.get(remotepath=self.remote_path, localpath=self.local_path)
6. 展示下载过程
为了将下载程序执行步骤实时展示到输出框,这里需要引入 PyQt5 的信号处理机制。
由于 PyQt 建议只在主线程中操作界面,可以发现我们在 main.py 中调用 DownloadLog.main 方法时创建了一个新的线程。
所有的 GUI 程序都是事件驱动的,事件可能由用户触发,比如点击 下载 按钮事件,也可能由程序触发,比如我们现在要实现的展示下载过程的功能,就需要使用程序主动触发事件。
在 PyQt5 中通过 Signal 信号来处理事件,其基本使用步骤如下:
自定义一个 CommunicateSignal 类,继承自 PyQt5 的 QObject 类,里面封装自定义的 Signal 信号(Signal 实例对象的初始化参数指定的类型,就是发出信号对象时,传递的参数数据类型。因为 PyQt5 底层是 C++ 开发的,必须指定类型)。
class CommunicateSignal(QObject): text_print = pyqtSignal(str)
定义主线程执行的函数处理 Signal 信号(通过 connect 方法绑定)。
# 自定义信号处理函数 self.comm_signal = CommunicateSignal() self.comm_signal.text_print.connect(self.show_text)
在 DownloadLog 线程需要操作界面的时候,就通过自定义对象(CommunicateSignal)发出信号(使用 emit 方法发出信号),所以在实例化 DownloadLog 时会将 comm_signal 传递进去。
# 通过该信号对象的 emit 方法发出信号,emit 方法的参数传递必要的数据。 # 参数类型遵循定义 Signal 时指定的类型。 self.comm_signal.text_print.emit(text)
主线程信号处理函数,被触发执行,获取 Signal 里面的参数,执行必要的更新界面操作,这里将每次通过事件传过来的文本内容展示到输出框内。
def show_text(self, text): """将文本内容追加到程序「展示框」""" self.textBrowser.append(text)
7. 效果展示
通过以上步骤我们完成的程序设计,现在可以验证下这个下载日志文件的小程序了:
查看下载结果:
总结
我们通过 PyQt5 实现了一个下载远程服务器日志文件的小程序,其实它不止可以用来下载日志,同样可以用来下载其他文件。 借助 PyQt5 强大的能力,我们可以通过“拖拉拽”的形式很容易地实现桌面端程序,只需要将原来的 Python 脚本绑定到 UI 程序的事件中,就实现了命令行程序到桌面程序的演进。 接下来你可以根据自己的需求来定制自己的桌面小程序啦~
资料参考:
https://download.qt.io/archive/qt/5.14/5.14.2/

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
去哪儿的常态化容量保障是怎么做的?
大多数时候,我们聊的都是“双十一”等大型活动下的容量保障,但除了个别典型峰值场景外,系统日常也会有各类容量保障的需求,去哪儿网作为国内最大的旅行平台之一,在各类场景中摸索出了一套常态化的容量保障方法。 平台从 2019 年的 1.7 倍流量即不可用,到 2022 年的 4 倍主要流量 0 故障,在最近两三年的时间里,去哪儿的容量保障核心做了哪些工作?我们来一探究竟。 作者介绍 去哪儿 资深质量保障专家-付亚南 TakinTalks 社区专家团成员,2014 年加入去哪儿网,负责过机票主系统、低价库、运价等业务质量保障工作,擅长自动化测试和性能测试。目前主要负责机票辅营相关业务,承担去哪儿网稳定性相关实践和落地。2018 年获得 TC 系统稳定性保障最佳测试方案;2020 年 TC 压测实践项目奖; 温馨提醒:本文约 5000 字,预计花费 8 分钟阅读。 微信公众号后台回复“交流”进入读者交流群;回复“2201”获取讲师课件。 背景 2019 年 3 月 22 日,五一放假通知发布后,我们去哪儿平台的流量很快增加了 1.7 倍,APP 受到流量暴涨的冲击,很快有一些服务就出现了...
- 下一篇
官宣!Hippo4j 1.4.x 新版本正式发布,探索更多玩法
2022 年 11 月 06 日,Hippo4j 1.4.3 版本正式发布! Hippo4j 是一个线程池框架,基于 JDK 原生线程池扩展了诸多功能,比如:运行时动态变更线程池参数、采集线程池运行时数据以及多种维度线程池报警等,为业务系统提高线上运行保障能力。 项目自 2021 年 6 月份开源,一直保持快速迭代,共经历 17 次版本发布,已知 23 家公司登记使用。截止目前,共计 83 位开源社区小伙伴参与贡献,这也是 Hippo4j 能保持快速迭代的原因。 GitHub: https://github.com/opengoofy/hippo4j Gitee: https://gitee.com/magegoofy/hippo4j 功能列表 项目使用 Hippo4j 后,提供以下功能支持: 全局管控 - 管理应用线程池实例。 动态变更 - 应用运行时动态变更线程池参数,包括但不限于:核心、最大线程数、阻塞队列容量、拒绝策略等。 通知报警 - 内置四种报警通知策略,线程池活跃度、容量水位、拒绝策略以及任务执行时间超长。 数据采集 - 采集线程池运行时数据,采集方式有:日志打印、内置采...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS关闭SELinux安全模块
- Windows10,CentOS7,CentOS8安装Nodejs环境
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- SpringBoot2更换Tomcat为Jetty,小型站点的福音
- Mario游戏-低调大师作品
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- CentOS7安装Docker,走上虚拟化容器引擎之路
- CentOS7编译安装Gcc9.2.0,解决mysql等软件编译问题
- SpringBoot2整合Thymeleaf,官方推荐html解决方案