本文目录导读:
- Kivy - 移动端App案例:简单的记事本
- PyQt5 - 桌面端案例:跨平台文件管理器
- web应用案例:简单的在线计算器(Flask)
- 使用跨平台模块:系统信息获取
- 数据库跨端案例:简单的SQLite数据管理器
我来介绍几个Python实现跨端运行的实际案例:
Kivy - 移动端App案例:简单的记事本
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
from kivy.uix.textinput import TextInput
from kivy.uix.label import Label
from kivy.uix.popup import Popup
class NoteApp(App):
def build(self):
layout = BoxLayout(orientation='vertical', padding=10, spacing=10)
# 标题
title_label = Label(text='我的记事本', size_hint=(1, 0.1))
layout.add_widget(title_label)
# 输入框
self.note_input = TextInput(
hint_text='请输入笔记内容...',
multiline=True,
size_hint=(1, 0.6)
)
layout.add_widget(self.note_input)
# 按钮区
btn_layout = BoxLayout(size_hint=(1, 0.1), spacing=10)
save_btn = Button(text='保存笔记')
save_btn.bind(on_press=self.save_note)
btn_layout.add_widget(save_btn)
load_btn = Button(text='加载笔记')
load_btn.bind(on_press=self.load_note)
btn_layout.add_widget(load_btn)
layout.add_widget(btn_layout)
return layout
def save_note(self, instance):
content = self.note_input.text
try:
with open('note.txt', 'w', encoding='utf-8') as f:
f.write(content)
self.show_popup('成功', '笔记已保存')
except Exception as e:
self.show_popup('错误', f'保存失败:{str(e)}')
def load_note(self, instance):
try:
with open('note.txt', 'r', encoding='utf-8') as f:
content = f.read()
self.note_input.text = content
self.show_popup('成功', '笔记已加载')
except FileNotFoundError:
self.show_popup('提示', '暂无保存的笔记')
except Exception as e:
self.show_popup('错误', f'加载失败:{str(e)}')
def show_popup(self, title, message):
popup_content = BoxLayout(orientation='vertical', padding=10)
popup_content.add_widget(Label(text=message))
close_btn = Button(text='关闭', size_hint=(1, 0.3))
popup = Popup(title=title, content=popup_content, size_hint=(0.8, 0.4))
close_btn.bind(on_press=popup.dismiss)
popup_content.add_widget(close_btn)
popup.open()
if __name__ == '__main__':
NoteApp().run()
PyQt5 - 桌面端案例:跨平台文件管理器
import sys
import os
from PyQt5.QtWidgets import *
from PyQt5.QtCore import Qt
class FileManager(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.setWindowTitle('跨平台文件管理器')
self.setGeometry(300, 300, 800, 600)
# 中心组件
central_widget = QWidget()
self.setCentralWidget(central_widget)
# 主布局
layout = QVBoxLayout()
central_widget.setLayout(layout)
# 工具栏
toolbar = QHBoxLayout()
self.path_input = QLineEdit()
self.path_input.setText(os.getcwd())
self.path_input.returnPressed.connect(self.change_path)
go_btn = QPushButton('前往')
go_btn.clicked.connect(self.change_path)
refresh_btn = QPushButton('刷新')
refresh_btn.clicked.connect(self.refresh)
toolbar.addWidget(QLabel('路径:'))
toolbar.addWidget(self.path_input)
toolbar.addWidget(go_btn)
toolbar.addWidget(refresh_btn)
layout.addLayout(toolbar)
# 文件列表
self.file_list = QListWidget()
self.file_list.itemDoubleClicked.connect(self.open_item)
layout.addWidget(self.file_list)
# 状态栏
self.statusBar().showMessage('就绪')
# 初始化显示
self.refresh()
def change_path(self):
path = self.path_input.text()
if os.path.exists(path):
os.chdir(path)
self.refresh()
else:
QMessageBox.warning(self, '错误', '路径不存在')
def refresh(self):
self.file_list.clear()
current_path = os.getcwd()
self.path_input.setText(current_path)
try:
items = os.listdir(current_path)
for item in items:
item_path = os.path.join(current_path, item)
if os.path.isdir(item_path):
self.file_list.addItem(f'📁 {item}')
else:
self.file_list.addItem(f'📄 {item}')
self.statusBar().showMessage(f'共 {len(items)} 个文件/文件夹')
except Exception as e:
QMessageBox.warning(self, '错误', str(e))
def open_item(self, item):
text = item.text()
# 去除图标
name = text[2:] if text.startswith('📁') or text.startswith('📄') else text
path = os.path.join(os.getcwd(), name)
if os.path.isdir(path):
os.chdir(path)
self.refresh()
else:
QMessageBox.information(self, '文件信息',
f'文件名: {name}\n路径: {path}')
if __name__ == '__main__':
app = QApplication(sys.argv)
window = FileManager()
window.show()
sys.exit(app.exec_())
web应用案例:简单的在线计算器(Flask)
from flask import Flask, render_template_string, request, jsonify
import os
app = Flask(__name__)
# HTML模板
HTML_TEMPLATE = '''
<!DOCTYPE html>
<html>
<head>跨平台计算器</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
body {
font-family: Arial, sans-serif;
max-width: 500px;
margin: 50px auto;
padding: 20px;
background-color: #f5f5f5;
}
.calculator {
background: white;
padding: 20px;
border-radius: 10px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
input, select, button {
display: block;
width: 100%;
margin: 10px 0;
padding: 10px;
font-size: 16px;
border: 1px solid #ddd;
border-radius: 5px;
box-sizing: border-box;
}
button {
background-color: #4CAF50;
color: white;
border: none;
cursor: pointer;
font-weight: bold;
}
button:hover {
background-color: #45a049;
}
.result {
margin-top: 20px;
padding: 15px;
background-color: #e7f3fe;
border-radius: 5px;
text-align: center;
font-size: 20px;
font-weight: bold;
}
</style>
</head>
<body>
<div class="calculator">
<h2>跨平台计算器</h2>
<input type="number" id="num1" placeholder="输入第一个数字" step="any">
<select id="operation">
<option value="add">+ 加法</option>
<option value="subtract">- 减法</option>
<option value="multiply">× 乘法</option>
<option value="divide">÷ 除法</option>
</select>
<input type="number" id="num2" placeholder="输入第二个数字" step="any">
<button onclick="calculate()">计算</button>
<div class="result" id="result">等待计算...</div>
</div>
<script>
function calculate() {
const num1 = parseFloat(document.getElementById('num1').value);
const num2 = parseFloat(document.getElementById('num2').value);
const operation = document.getElementById('operation').value;
if (isNaN(num1) || isNaN(num2)) {
document.getElementById('result').innerText = '请输入有效的数字';
return;
}
fetch('/calculate', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
num1: num1,
num2: num2,
operation: operation
})
})
.then(response => response.json())
.then(data => {
if (data.error) {
document.getElementById('result').innerText = data.error;
} else {
document.getElementById('result').innerText = `结果: ${data.result}`;
}
});
}
</script>
</body>
</html>
'''
@app.route('/')
def index():
return render_template_string(HTML_TEMPLATE)
@app.route('/calculate', methods=['POST'])
def calculate():
data = request.get_json()
num1 = data['num1']
num2 = data['num2']
operation = data['operation']
try:
if operation == 'add':
result = num1 + num2
elif operation == 'subtract':
result = num1 - num2
elif operation == 'multiply':
result = num1 * num2
elif operation == 'divide':
if num2 == 0:
return jsonify({'error': '除数不能为零'})
result = num1 / num2
else:
return jsonify({'error': '未知操作'})
return jsonify({'result': result})
except Exception as e:
return jsonify({'error': str(e)})
if __name__ == '__main__':
port = int(os.environ.get('PORT', 5000))
app.run(host='0.0.0.0', port=port, debug=True)
使用跨平台模块:系统信息获取
import platform
import os
import sys
import psutil
import socket
class SystemInfo:
def __init__(self):
self.info = {}
def collect_info(self):
"""收集系统信息"""
self.info['操作系统'] = platform.system()
self.info['操作系统版本'] = platform.version()
self.info['架构'] = platform.machine()
self.info['处理器'] = platform.processor()
self.info['主机名'] = socket.gethostname()
self.info['Python版本'] = sys.version
# CPU信息
self.info['CPU核心数'] = psutil.cpu_count()
self.info['CPU使用率'] = f"{psutil.cpu_percent()}%"
# 内存信息
memory = psutil.virtual_memory()
self.info['总内存'] = self.format_bytes(memory.total)
self.info['可用内存'] = self.format_bytes(memory.available)
self.info['内存使用率'] = f"{memory.percent}%"
# 磁盘信息
disk = psutil.disk_usage('/')
self.info['磁盘总容量'] = self.format_bytes(disk.total)
self.info['磁盘已使用'] = self.format_bytes(disk.used)
self.info['磁盘可用'] = self.format_bytes(disk.free)
self.info['磁盘使用率'] = f"{disk.percent}%"
# 进程信息
self.info['运行进程数'] = len(psutil.pids())
def format_bytes(self, bytes_num):
"""格式化字节数"""
for unit in ['B', 'KB', 'MB', 'GB', 'TB']:
if bytes_num < 1024:
return f"{bytes_num:.2f} {unit}"
bytes_num /= 1024
return f"{bytes_num:.2f} PB"
def display_info(self):
"""显示系统信息"""
print("=" * 50)
print(f"系统信息 - {self.info['主机名']}")
print("=" * 50)
for key, value in self.info.items():
print(f"{key}: {value}")
print("=" * 50)
def save_to_file(self, filename='system_info.txt'):
"""保存系统信息到文件"""
with open(filename, 'w', encoding='utf-8') as f:
f.write("系统信息报告\n")
f.write("=" * 50 + "\n")
for key, value in self.info.items():
f.write(f"{key}: {value}\n")
print(f"信息已保存到 {filename}")
# 跨平台命令行工具
class SystemMonitor:
def __init__(self):
self.sys_info = SystemInfo()
def run(self):
"""运行系统监控"""
while True:
print("\n系统监控工具")
print("1. 查看系统信息")
print("2. 保存系统信息")
print("3. 退出")
choice = input("请选择 (1-3): ").strip()
if choice == '1':
self.sys_info.collect_info()
self.sys_info.display_info()
elif choice == '2':
self.sys_info.collect_info()
self.sys_info.save_to_file()
elif choice == '3':
print("再见!")
break
else:
print("无效选择,请重试")
if __name__ == '__main__':
# 检查是否安装了psutil
try:
import psutil
except ImportError:
print("请安装psutil: pip install psutil")
sys.exit(1)
monitor = SystemMonitor()
monitor.run()
数据库跨端案例:简单的SQLite数据管理器
import sqlite3
import os
import json
from datetime import datetime
class DataManager:
def __init__(self, db_name='cross_platform.db'):
self.db_name = db_name
self.conn = None
self.init_database()
def init_database(self):
"""初始化数据库"""
self.conn = sqlite3.connect(self.db_name)
cursor = self.conn.cursor()
# 创建用户表
cursor.execute('''
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
username TEXT UNIQUE NOT NULL,
email TEXT,
created_at TEXT,
updated_at TEXT
)
''')
# 创建任务表
cursor.execute('''
CREATE TABLE IF NOT EXISTS tasks (
id INTEGER PRIMARY KEY AUTOINCREMENT,
user_id INTEGER,
title TEXT NOT NULL,
description TEXT,
status TEXT DEFAULT 'pending',
created_at TEXT,
FOREIGN KEY (user_id) REFERENCES users (id)
)
''')
self.conn.commit()
def add_user(self, username, email):
"""添加用户"""
try:
cursor = self.conn.cursor()
now = datetime.now().isoformat()
cursor.execute('''
INSERT INTO users (username, email, created_at, updated_at)
VALUES (?, ?, ?, ?)
''', (username, email, now, now))
self.conn.commit()
return {'success': True, 'message': f'用户 {username} 添加成功'}
except sqlite3.IntegrityError:
return {'success': False, 'message': f'用户 {username} 已存在'}
def add_task(self, user_id, title, description=''):
"""添加任务"""
cursor = self.conn.cursor()
now = datetime.now().isoformat()
cursor.execute('''
INSERT INTO tasks (user_id, title, description, created_at)
VALUES (?, ?, ?, ?)
''', (user_id, title, description, now))
self.conn.commit()
return {'success': True, 'message': '任务添加成功'}
def get_users(self):
"""获取所有用户"""
cursor = self.conn.cursor()
cursor.execute('SELECT * FROM users')
users = cursor.fetchall()
return [{'id': u[0], 'username': u[1], 'email': u[2]} for u in users]
def get_tasks(self, user_id=None):
"""获取任务"""
cursor = self.conn.cursor()
if user_id:
cursor.execute('SELECT * FROM tasks WHERE user_id = ?', (user_id,))
else:
cursor.execute('SELECT * FROM tasks')
tasks = cursor.fetchall()
return [{'id': t[0], 'user_id': t[1], 'title': t[2],
'description': t[3], 'status': t[4]} for t in tasks]
def export_to_json(self, filename='data_export.json'):
"""导出数据到JSON"""
data = {
'users': self.get_users(),
'tasks': self.get_tasks()
}
with open(filename, 'w', encoding='utf-8') as f:
json.dump(data, f, ensure_ascii=False, indent=2)
return {'success': True, 'message': f'数据已导出到 {filename}'}
def import_from_json(self, filename='data_export.json'):
"""从JSON导入数据"""
try:
with open(filename, 'r', encoding='utf-8') as f:
data = json.load(f)
# 导入用户
for user in data['users']:
self.add_user(user['username'], user['email'])
# 导入任务
for task in data['tasks']:
self.add_task(task['user_id'], task['title'], task['description'])
return {'success': True, 'message': '数据导入成功'}
except FileNotFoundError:
return {'success': False, 'message': '文件不存在'}
def close(self):
"""关闭数据库连接"""
if self.conn:
self.conn.close()
def main():
"""主函数"""
manager = DataManager()
while True:
print("\n" + "="*50)
print("跨平台数据管理器")
print("="*50)
print("1. 添加用户")
print("2. 查看用户")
print("3. 添加任务")
print("4. 查看任务")
print("5. 导出数据")
print("6. 导入数据")
print("7. 退出")
choice = input("\n请选择 (1-7): ").strip()
if choice == '1':
username = input("用户名: ").strip()
email = input("邮箱: ").strip()
result = manager.add_user(username, email)
print(result['message'])
elif choice == '2':
users = manager.get_users()
if users:
print("\n用户列表:")
for user in users:
print(f"ID: {user['id']}, 用户名: {user['username']}, 邮箱: {user['email']}")
else:
print("暂无用户")
elif choice == '3':
user_id = int(input("用户ID: "))
title = input("任务标题: ").strip()
description = input("任务描述: ").strip()
result = manager.add_task(user_id, title, description)
print(result['message'])
elif choice == '4':
tasks = manager.get_tasks()
if tasks:
print("\n任务列表:")
for task in tasks:
print(f"ID: {task['id']}, 标题: {task['title']}, 状态: {task['status']}")
else:
print("暂无任务")
elif choice == '5':
result = manager.export_to_json()
print(result['message'])
elif choice == '6':
result = manager.import_from_json()
print(result['message'])
elif choice == '7':
manager.close()
print("再见!")
break
if __name__ == '__main__':
main()
这些案例展示了Python跨端运行的不同方式:
- Kivy:适合移动端和桌面端App开发
- PyQt5:专业的桌面应用开发框架
- Flask Web:适合Web应用,可在任何有浏览器的设备上运行
- 系统工具:使用platform、psutil等跨平台库
- 数据库管理:使用SQLite实现数据持久化
选择哪种方案取决于:
- 目标平台(移动端/桌面端/Web端)
- 功能复杂度
- 用户体验要求
- 开发时间限制
每个框架都有其优势,选择最适合项目需求的方案即可。
标签: 运行案例