Mooreの小站

Moore的个人小站

Python 第四五节

2025-03-30

一、文件IO

1、数据来源

(1)模型训练

  • 需要大量的数据

  • 通用的共享的开源素材,直接下载使用(开源数据集)

  • 垂直领域的素材(自己公司所有),别人可以买

(2)保存数据

  • 如果有多条数据,需要保存到JSON文件里面

    • 特点:源数据格式是什么样的,需要先进行数据处理

(3)文件保存到Excel

  • 使用openpyxl 库 → 合并单元格、单元格美化

  • 安装pip install openpyxl

  • 步骤

  • 打开或创建一个Excel文件

  • 选择工作表

  • 给单元格设置内容

import openpyxl

# 打开或创建一个工作簿
wb = openpyxl.Workbook()

# 激活表格
ws = wb.active

# 创建表头列表
headers = ['序号', '姓名', '年龄', '性别', '电话']

# 将表头写入表格
ws.append(headers)

# 创建数据列表
data = [
   {
      '姓名': '张三',
      '年龄': 18,
      '性别': '男',
      '电话': '1234567890'
   }, {
      '姓名': '李四',
      '年龄': 20,
      '性别': '女',
      '电话': '0987654321'
   }, {
      '姓名': '王五',
      '年龄': 22,
      '性别': '男',
      '电话': '1111111111'
   }
]

# 将数据写入表格
for index, row in enumerate(data, start=1):
    ws.append([index, row['姓名'], row['年龄'], row['性别'], row['电话']])

# 保存工作簿
wb.save('./0330/demo.xlsx')

2、文件解析

(1)JSON文件解析

import json
import os

# 读取JSON文件
file_path = './0330/user_list.json'

if os.path.exists(file_path):
    # 打开JSON文件
    with open(file_path, 'r', encoding='utf-8') as f:
        # 使用JSON库读取
        user_list = json.load(f)
        # 遍历JSON进行输出
        for user in user_list:
            print(f'姓名: {user["name"]}, 年龄: {user["age"]}, 地址: {user["addr"]}')
else:
    print('文件不存在')

(2)Excel文件解析

import os
import openpyxl
file_path = './0330/demo.xlsx'

# 读取Excel文件
if os.path.exists(file_path):
    # 打开Excel文件
    workbook = openpyxl.load_workbook(file_path)
    # 选择工作表
    sheet = workbook['Sheet']
    # 批量读取单元格的值
    for row in sheet.iter_rows(min_row=2, values_only=True):
        # row是一个元组,包含每一行的单元格值
        print(f'序号: {row[0]}, 姓名: {row[1]}, 年龄: {row[2]}, 性别: {row[3]}, 电话: {row[4]}')
    # 关闭工作簿
    workbook.close()
else:
    print('文件不存在')

二、爬虫

向某个网站发起HTTP请求,得到响应(一个网页的源码→HTML),解析HTML,找到你先要的东西,然后做点处理

1、网络请求

使用request

  • 请求方式:get、post、delete、put等

(1)发起HTTP请求

①get

import requests

response = requests.get("https://www.nipic.com/show/45718130.html/")
print(response.text)

②post

import requests
import json

data = {
    'username': 'zhangsan',
    'password': '76209400'
}

headers = {
    'Content-Type': 'application/json'
}

# 自己电脑上的JAVA项目
response = requests.post("http://localhost:8888/public_rental_housing_ssm_war_exploded/admin/login/",
    data=json.dumps(data),headers=headers)  # 将字典数据转为JSON,且指定请求头媒体类型为JSON
print(response.text)

(2)response

  • text → 获取响应的文本内容

  • content → 获取响应的字节内容

2、实战

(1)爬取百度二维码图片

所用图片:https://pss.bdstatic.com/static/superman/img/qrcode_download-02b84e1f66.png

  • 步骤:

    • 使用网络请求访问该网址→HTML代码→requests的get方法

    • 取出里面的内容→图片的内容

    • 保存图片→open以wb方式打开

import requests
from urllib.parse import urlparse

# 图片URL
url = 'https://pss.bdstatic.com/static/superman/img/qrcode_download-02b84e1f66.png'

# 扩展:从URL中提取文件名
filename = urlparse(url).path.split('/')[-1]

# 发送GET请求下载图片
response = requests.get(url)

# 检查请求是否成功
if response.status_code == 200:
    # 以二进制写入模式打开文件,使用原始文件名
    with open('./0330/' + filename, 'wb') as f:
        # 将内容写入文件
        f.write(response.content)
    print(f'图片下载成功!保存为: {filename}')
else:
    print(f'下载失败,状态码:{response.status_code}')

(2)爬取昵图网图片

返回的HTML代码中会包含很多图片(img标签),获取每个标签(图片)对应的图片,然后分别用request请求一下

网址:

https://www.nipic.com/show/45718130.html/
  • 步骤:

    • 使用网络请求访问该网址→html代码→requests的get方法

    • 解析HTML代码,找到img标签→获取src属性→多个

      • 使用beautifulSoup4lxml 两个库

    • 通过request请求去访问src里面指定的路径,得到图片的二进制流

    • 保存图片

import requests
from bs4 import BeautifulSoup
import os
from urllib.parse import urljoin
import time

def download_images(url):
    # 创建保存图片的目录
    save_dir = 'downloaded_images'
    if not os.path.exists(save_dir):
        os.makedirs(save_dir)
    
    # 设置请求头,模拟浏览器
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
    }
    
    try:
        # 获取网页内容
        response = requests.get(url, headers=headers)
        response.raise_for_status()  # 检查请求是否成功
        
        # 使用BeautifulSoup解析HTML
        soup = BeautifulSoup(response.content, 'lxml')
        
        # 查找所有图片标签
        img_tags = soup.find_all('img')
        
        # 遍历并下载图片
        for img in img_tags:
            # 获取图片URL
            img_url = img.get('src')
            if not img_url:
                continue
                
            # 确保URL是完整的
            img_url = urljoin(url, img_url)
            
            try:
                # 下载图片
                img_response = requests.get(img_url, headers=headers)
                img_response.raise_for_status()
                
                # 从URL中获取文件名
                filename = os.path.basename(img_url)
                filepath = os.path.join(save_dir, filename)
                
                # 保存图片
                with open(filepath, 'wb') as f:
                    f.write(img_response.content)
                
                print(f'成功下载图片: {filename}')
                
                # 添加延迟,避免请求过快
                time.sleep(1)
                
            except Exception as e:
                print(f'下载图片失败: {img_url}')
                print(f'错误信息: {str(e)}')
                
    except Exception as e:
        print(f'获取网页失败: {url}')
        print(f'错误信息: {str(e)}')

# 运行爬虫
url = 'https://www.nipic.com/show/45718130.html'
download_images(url)

三、PyQt图形界面编程

1、使用PyQt界面

安装pip install PyQt5

  • 创建一个界面应用户程序

  • 创建一个窗口

    • 设置窗口标题 setWindowTitle()

    • 设置窗户口图标 setWindowIcon()

    • 设置窗口大小 resize()

    • 调整窗口位置以及大小 setGeometry()

  • 创建各种组件:文本框,密码框,单选,按钮等

2、文本框

(1)创建文本框

文本框主要用于显示文字,使用QLabel()

  • 方案一:QLabel('example')

    • 创建的时候顺便写好文字

  • 方案二:

    • 创建的时候不写文字 QLabel()

    • 通过调用 setText()

(2)指定文本框的父级元素

  • 也就是显示在哪个窗口

  • 需要指定显示在那个窗口,不指定也就不显示在任何窗口上

  • 一样通过setGeometry() 设置文本位置和大小

  • 方案一:

    • 使用setParent()

  • 方案二:

    • 在创建的时候就顺便指定了 QLable(exanple_window)

3、图片控件

借助QLabel() 来实现的,然后使用QPixmap() 来指定图片

4、单行文本控件

使用QLineEdit()

  • 输出模式

    • QLineEdit.password → 密文模式

    • QLineEdit.passwordEchoOnEdit → 编辑时可见,不编辑时不可见

    • QLineEdit.NoEcho → 不显示

    • QLineEdit.Normal → 普通明文模式

5、多行文本控件

使用QTextEdit()

  • 如何创建

  • 如何设置文本内容

  • 如何获取文本内容

    • setPlainText()

    • setHtml() → 可以包含HTML标签,如使用<br><strong></strong><p></p><h1></h1>

      • 说明也可以显示多媒体元素(图片<img></img>、视频<video></video> 、音频<audio></audio>

  • 清空文本内容:clear()

6、按钮

  • 普通按钮

    • 使用QPushButton() ,使用clicked 来实现按下后操作

  • 单选按钮

    • 使用QRadioButton() ,使用toggled 来处理切换操作,按钮组

  • 复选按钮

    • 使用QCheckBox(),使用isChecked 判断某个复选框被选中

7、对话框

(2)QMessageBox()

  • 信息提示框,包含warninginformationcriticalquestion

  • 修改按钮文字:

    • 自带的默认按钮:Ok,Yes,No,Cancel

    • 自定义对话框

# 默认方法
tip_box = QMessageBox()
tip_box.question(
  example_window,
  'example_title',
  'example_message',
  buttons= QMessages.Ok | QMessageBox.Cancel
)

# 自定义对话框
tip_box_1 = QMessageBox()
# 自定义标题和文字
tip_box_1.setWindowTitle('example_title')
tip_box_1.setText('example_text')
# 自己创建两个按钮,作为对话框的按钮来用
yes_button = QPushButton('是')
no_button = QPushButton('否')
# 将按钮添加到对话框
tip_box_1.addButton(yes_btn,QMessageBox.AcceptRole)  # 作为接受按钮
tip_box_1.addButton(no_btn,QMessageBox.RejectRole) # 作为拒绝按钮
# 执行显示修改后的对话框
tip_box_1.exec()

(3)QInputDialog()

  • 带输入框的对话框

q_dialog = QInputDialog()
q_dialog.getText(example_window, 'example_title')

8、布局

(1)类型

  • 水平布局QHBoxLayout

  • 垂直布局QVBoxLayout

  • 表单布局QFormLayout

  • 网络布局QGridLayout

  • 嵌套布局

(2)示例

  • 创建一个挂件QWidget ,并设置该挂件的布局方式为垂直布局

# left_view.py
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QPushButton

class LeftView(QWidget):
    def __init__(self):
        super().__init__()
        self.btn1 = QPushButton("打开文件")
        self.btn2 = QPushButton("打开文件夹")
        v_layout = QVBoxLayout()
        self.setLayout(v_layout)
        # 添加按钮
        v_layout.addWidget(self.btn1)
        v_layout.addWidget(self.btn2)
# main.py
from left_view import LeftView
from PyQt5.QtWidgets import QApplication
import sys

if __name__ == "__main__":
    app = QApplication(sys.argv)
    left_view = LeftView()
    left_view.show()
    sys.exit(app.exec_())

三、课后复习

1、找一个网页实现爬虫

  • 顺便回顾递归算法,怎么实现递归

import requests
import os
from bs4 import BeautifulSoup
import time
from urllib.parse import urljoin
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry

def create_session():
    """创建一个带重试机制的会话"""
    session = requests.Session()
    
    # 配置重试策略
    retries = Retry(
        total=5,  # 总共重试5次
        backoff_factor=1,  # 重试之间的等待时间
        status_forcelist=[500, 502, 503, 504]  # 需要重试的HTTP状态码
    )
    
    # 将重试策略应用到会话
    adapter = HTTPAdapter(max_retries=retries)
    session.mount('http://', adapter)
    session.mount('https://', adapter)
    
    # 设置请求头,模拟浏览器
    session.headers.update({
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
    })
    
    return session

def get_original_image_url(session, detail_url):
    """获取原图URL"""
    try:
        response = session.get(detail_url, verify=False)
        if response.status_code == 200:
            soup = BeautifulSoup(response.text, 'html.parser')
            # 查找原图链接,通常在id为wallpaper的img标签中
            img_tag = soup.find('img', id='wallpaper')
            if img_tag and img_tag.get('src'):
                return img_tag['src']
    except Exception as e:
        print(f"获取原图链接失败: {detail_url}")
        print(f"错误信息: {str(e)}")
    return None

def download_wallpaper(session, url, save_dir):
    """下载单张壁纸"""
    try:
        response = session.get(url, verify=False)
        if response.status_code == 200:
            # 使用原图URL中的文件名
            filename = url.split('/')[-1]
            # 检查文件类型
            file_ext = os.path.splitext(filename)[1].lower()
            if file_ext not in ['.jpg', '.jpeg', '.png', '.webp']:
                print(f"不支持的文件类型: {filename}")
                return False
                
            filepath = os.path.join(save_dir, filename)
            
            if os.path.exists(filepath):
                print(f"文件已存在: {filename}")
            else:
                with open(filepath, 'wb') as f:
                    f.write(response.content)
            print(f"成功下载: {filename}")
            return True
    except Exception as e:
        print(f"下载失败: {url}")
        print(f"错误信息: {str(e)}")
    return False

def crawl_page(session, url, save_dir, page=1, max_pages=10, retry_count=0, max_retries=3):
    """递归爬取壁纸页面"""
    if retry_count >= max_retries:
        print(f"已达到最大重试次数 {max_retries},停止爬取")
        return
        
    if page > max_pages:
        print("达到最大页数,重新从第一页开始")
        # 重新从第一页开始,增加重试计数
        crawl_page(session, url, save_dir, 1, max_pages, retry_count + 1, max_retries)
        return
    
    print(f"正在爬取第 {page} 页...")
    
    try:
        page_url = f"{url}&page={page}"
        response = session.get(page_url, verify=False)
        soup = BeautifulSoup(response.text, 'html.parser')
        
        # 找到所有壁纸预览图的父级元素
        wallpaper_links = soup.find_all('a', class_='preview')
        
        if not wallpaper_links:
            print(f"第 {page} 页没有找到壁纸,继续下一页")
            # 继续爬取下一页,而不是重新开始
            crawl_page(session, url, save_dir, page, max_pages, retry_count, max_retries)
            return
            
        for link in wallpaper_links:
            # 获取详情页URL
            detail_url = link.get('href')
            if detail_url:
                print(f"正在处理: {detail_url}")
                # 获取原图URL
                original_url = get_original_image_url(session, detail_url)
                if original_url:
                    # 下载原图
                    download_wallpaper(session, original_url, save_dir)
                    # 添加延时,避免请求过于频繁
                    time.sleep(3)
        
        # 递归爬取下一页
        crawl_page(session, url, save_dir, page + 1, max_pages, retry_count, max_retries)
        
    except Exception as e:
        print(f"爬取页面失败: {page}")
        print(f"错误信息: {str(e)}")

def main():
    # 禁用SSL验证警告
    import urllib3
    urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
    
    # 设置壁纸网站URL
    base_url = "https://wallhaven.cc/search?categories=110&purity=100&atleast=1920x1080&topRange=1M&sorting=favorites&order=desc&ai_art_filter=1"
    
    # 设置保存目录
    save_dir = "wallpapers"
    if not os.path.exists(save_dir):
        os.makedirs(save_dir)
    
    # 创建会话
    session = create_session()
    
    # 开始爬取
    crawl_page(session, base_url, save_dir)

if __name__ == "__main__":
    main()

2、绘制一个登录注册页面

  • 并实现登录注册请求,和相关提示

from PyQt5.QtWidgets import (QApplication, QWidget, QLabel, QLineEdit, 
                           QPushButton, QRadioButton, QMessageBox)
from PyQt5.QtGui import QIcon, QPixmap
import sys
import json
import requests

class LoginWindow(QWidget):
    def __init__(self):
        super().__init__()
        self.login_widgets = []  # 存储登录相关组件
        self.register_widgets = []  # 存储注册相关组件
        self.initUI()
        
    def initUI(self):
        # 初始化窗口基本设置
        self.setWindowTitle('传一卓跃')
        self.setWindowIcon(QIcon('./0330/icon.jpg'))
        
        # 设置背景图
        self.pic_label = QLabel(self)
        pic = QPixmap('./downloaded_images/18295875_213833592103_2.jpg')
        self.pic_label.setPixmap(pic)
        self.resize(pic.width(), pic.height())
        
        # 初始化登录界面
        self.init_login_ui()
        
    def init_login_ui(self):
        # 欢迎文字
        welcome_label = QLabel('欢迎登录', self)
        welcome_label.setStyleSheet('color: white; font-size: 30px;')
        welcome_label.setGeometry(30, 30, 300, 50)
        
        # 账号输入区域
        acc_label = QLabel('账号:', self)
        acc_label.setGeometry(30, 75, 170, 50)
        acc_label.setStyleSheet('color: white; font-size: 20px;')
        
        self.username_input = QLineEdit(self)
        self.username_input.setPlaceholderText('请输入账号')
        self.username_input.setGeometry(30, 120, 170, 30)
        self.username_input.setStyleSheet('border: 1px solid blue; padding: 5px;')
        
        # 密码输入区域
        pwd_label = QLabel('密码:', self)
        pwd_label.setGeometry(30, 150, 170, 50)
        pwd_label.setStyleSheet('color: white; font-size: 20px;')
        
        self.password_input = QLineEdit(self)
        self.password_input.setPlaceholderText('请输入密码')
        self.password_input.setGeometry(30, 195, 170, 30)
        self.password_input.setStyleSheet('border: 1px solid blue; padding: 5px;')
        self.password_input.setEchoMode(QLineEdit.Password)
        
        # 用户类型选择
        self.radio_admin = QRadioButton('管理员', self)
        self.radio_admin.setGeometry(30, 230, 170, 50)
        self.radio_admin.setStyleSheet('color: white; font-size: 20px;')
        self.radio_admin.setChecked(True)
        
        self.radio_user = QRadioButton('普通用户', self)
        self.radio_user.setGeometry(30, 270, 170, 50)
        self.radio_user.setStyleSheet('color: white; font-size: 20px;')
        
        # 登录按钮
        self.login_button = QPushButton('登录', self)
        self.login_button.setGeometry(30, 320, 170, 50)
        self.login_button.setStyleSheet('background-color: blue; color: white; font-size: 20px;')
        self.login_button.clicked.connect(self.handle_login)
        
        # 注册按钮
        self.register_button = QPushButton('注册', self)
        self.register_button.setGeometry(30, 380, 170, 50)
        self.register_button.setStyleSheet('background-color: green; color: white; font-size: 20px;')
        self.register_button.clicked.connect(self.show_register_ui)
        
        # 保存登录相关组件引用
        self.login_widgets = [welcome_label, acc_label, self.username_input,
                            pwd_label, self.password_input, self.radio_admin,
                            self.radio_user, self.login_button, self.register_button]
    
    def init_register_ui(self):
        # 注册标题
        reg_title = QLabel('用户注册', self)
        reg_title.setStyleSheet('color: white; font-size: 30px;')
        reg_title.setGeometry(30, 30, 300, 50)
        
        # 注册表单字段
        fields = ['账号', '密码', '姓名', '手机', '证件号码', '联系地址']
        self.reg_inputs = {}
        
        for i, field in enumerate(fields):
            # 创建标签
            label = QLabel(f'{field}:', self)
            label.setGeometry(30, 75 + i*70, 170, 50)
            label.setStyleSheet('color: white; font-size: 20px;')
            
            # 创建输入框
            input_box = QLineEdit(self)
            input_box.setPlaceholderText(f'请输入{field}')
            input_box.setGeometry(30, 120 + i*70, 170, 30)
            input_box.setStyleSheet('border: 1px solid blue; padding: 5px;')
            if field == '密码':
                input_box.setEchoMode(QLineEdit.Password)
            
            self.reg_inputs[field] = input_box
            self.register_widgets.extend([label, input_box])
        
        # 注册和返回按钮
        y_pos = 120 + len(fields)*70
        
        submit_btn = QPushButton('提交注册', self)
        submit_btn.setGeometry(30, y_pos, 170, 50)
        submit_btn.setStyleSheet('background-color: green; color: white; font-size: 20px;')
        submit_btn.clicked.connect(self.handle_register)
        
        back_btn = QPushButton('返回登录', self)
        back_btn.setGeometry(30, y_pos + 60, 170, 50)
        back_btn.setStyleSheet('background-color: gray; color: white; font-size: 20px;')
        back_btn.clicked.connect(self.show_login_ui)
        
        self.register_widgets.extend([reg_title, submit_btn, back_btn])
        
        # 初始隐藏所有注册组件
        for widget in self.register_widgets:
            widget.hide()
            
    def show_register_ui(self):
        # 隐藏登录组件
        for widget in self.login_widgets:
            widget.hide()
        
        # 确保注册组件已初始化
        if not self.register_widgets:
            self.init_register_ui()
            
        # 显示注册组件
        for widget in self.register_widgets:
            widget.show()
            
    def show_login_ui(self):
        # 隐藏注册组件
        for widget in self.register_widgets:
            widget.hide()
            
        # 显示登录组件
        for widget in self.login_widgets:
            widget.show()
            
    def handle_login(self):
        username = self.username_input.text()
        password = self.password_input.text()
        
        if not username or not password:
            QMessageBox.warning(self, '提示', '请输入账号和密码!')
            return
            
        # 根据用户类型选择不同的登录接口
        main_url = 'http://localhost:8888/public_rental_housing_ssm_war_exploded/'
        api_url = 'admin/login' if self.radio_admin.isChecked() else 'tenant/login'

        # 登录信息
        login_data = {'account': username, 'password': password}
        
        try:
            # 调用登录接口
            response = requests.post(main_url + api_url, 
                                   json=login_data,  # 使用json参数自动处理JSON序列化
                                   headers={'Content-Type': 'application/json'})
            
            # 将响应解析为JSON
            result = response.json()
            
            # 检查响应状态
            if result.get('code') == 200:  # 使用get方法安全获取code
                QMessageBox.information(self, '成功', '登录成功!')
            else:
                QMessageBox.warning(self, '错误', result.get('message', '未知错误'))
        except requests.exceptions.RequestException as e:
            QMessageBox.critical(self, '错误', f'网络请求失败:{str(e)}')
        except json.JSONDecodeError as e:
            QMessageBox.critical(self, '错误', f'响应数据格式错误:{str(e)}')
        except Exception as e:
            QMessageBox.critical(self, '错误', f'系统错误:{str(e)}')
            
    def handle_register(self):
        # 收集注册信息
        register_data = {
            'account': self.reg_inputs['账号'].text(),
            'password': self.reg_inputs['密码'].text(),
            'name': self.reg_inputs['姓名'].text(),
            'phone': self.reg_inputs['手机'].text(),
            'idCard': self.reg_inputs['证件号码'].text(),
            'address': self.reg_inputs['联系地址'].text()
        }
        
        # 验证必填字段
        if not all(register_data.values()):
            QMessageBox.warning(self, '提示', '请填写所有必填信息!')
            return
            
        try:
            # 调用注册接口
            response = requests.post(
                'http://localhost:8888/public_rental_housing_ssm_war_exploded/tenant/reg',
                json=register_data,  # 使用json参数自动处理JSON序列化
                headers={'Content-Type': 'application/json'}
            )
            
            # 将响应解析为JSON
            result = response.json()
            
            # 检查响应状态
            if result.get('code') == 200:
                QMessageBox.information(self, '成功', '注册成功!')
                self.show_login_ui()  # 返回登录界面
            else:
                QMessageBox.warning(self, '错误', result.get('message', '注册失败'))
        except requests.exceptions.RequestException as e:
            QMessageBox.critical(self, '错误', f'网络请求失败:{str(e)}')
        except json.JSONDecodeError as e:
            QMessageBox.critical(self, '错误', f'响应数据格式错误:{str(e)}')
        except Exception as e:
            QMessageBox.critical(self, '错误', f'系统错误:{str(e)}')

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

3、PyQt小扩展

  • 修改QInputDialog的按钮为中文

  • 使用文件选择框,获取用户选择文件(文件路径)

import sys
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QVBoxLayout, QInputDialog, QFileDialog


class Example(QWidget):
    def __init__(self):
        super().__init__()
        self.file_btn = None
        self.input_btn = None
        self.init_ui()

    def init_ui(self):
        layout = QVBoxLayout()

        # 创建按钮
        self.input_btn = QPushButton('打开输入对话框', self)
        self.file_btn = QPushButton('选择文件', self)

        # 连接按钮点击事件
        self.input_btn.clicked.connect(self.show_input_dialog)
        self.file_btn.clicked.connect(self.show_file_dialog)

        # 添加按钮到布局
        layout.addWidget(self.input_btn)
        layout.addWidget(self.file_btn)

        self.setLayout(layout)
        self.setGeometry(300, 300, 300, 150)
        self.setWindowTitle('PyQt 示例')
        self.show()

    def show_input_dialog(self):
        # 创建输入对话框
        dialog = QInputDialog(self)
        dialog.setWindowTitle('输入对话框')
        dialog.setLabelText('请输入内容:')

        # 修改按钮文本为中文
        dialog.setOkButtonText('确定')
        dialog.setCancelButtonText('取消')

        # 显示对话框
        ok = dialog.exec_()
        text = dialog.textValue()

        if ok:
            print(f'输入的内容: {text}')

    def show_file_dialog(self):
        # 创建文件选择对话框
        options = QFileDialog.Options()
        file_name, _ = QFileDialog.getOpenFileName(
            self,
            "选择文件",
            "",
            "所有文件 (*);;文本文件 (*.txt)",
            options=options
        )

        if file_name:
            print(f'选择的文件路径: {file_name}')


if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())