【Python入门系列】第八篇:Python中GUI编程和图形界面设计

JosieBook 2024-07-08 15:05:04 阅读 99

文章目录

前言一、Tkinter、PyQt和wxPython库简单使用1、Tkinter简单使用2、PyQt简单使用3、wxPython简单使用

二、Tkinter、PyQt和wxPython库实现计算器1、Tkinter实现计算器2、PyQt实现计算器3、wxPython实现计算器

三、Tkinter、PyQt和wxPython库简单QQ聊天1、Tkinter实现QQ聊天2、PyQt实现QQ聊天3、wxPython实现QQ聊天

四、Tkinter、PyQt和wxPython库贪吃蛇游戏1、Tkinter实现贪吃蛇游戏2、PyQt实现贪吃蛇游戏

总结


前言

Python中的GUI编程是指使用Python语言创建图形用户界面(GUI)的过程。通过GUI,用户可以与程序进行交互,通过按钮、菜单、文本框等控件来操作程序。

Python提供了多个库和框架来实现GUI编程,其中最常用的是Tkinter、wxPython、PyQt和PyGTK等。这些库提供了丰富的控件和功能,使开发者能够轻松地创建各种类型的图形界面。

在GUI编程中,通常使用窗口(Window)作为程序的主要界面。可以在窗口中添加各种控件,如按钮、标签、文本框、复选框等,用于与用户进行交互。通过事件处理机制,可以对用户的操作进行响应,执行相应的函数或方法。

图形界面设计是指创建具有良好用户体验的界面。在设计过程中,需要考虑界面布局、颜色搭配、控件的摆放位置等因素,以确保用户能够方便地使用程序。

一、Tkinter、PyQt和wxPython库简单使用

1、Tkinter简单使用

Tkinter 是 Python 中常用的 GUI 编程库,用于创建图形用户界面。下面是 Tkinter 的简单使用说明:

导入 Tkinter 模块:

<code>import tkinter as tk

创建主窗口:

root = tk.Tk()

添加控件:

可以添加各种控件,如标签、按钮、文本框等。例如,添加一个标签和一个按钮:

label = tk.Label(root, text="Hello, Tkinter!")code>

button = tk.Button(root, text="Click me!")code>

布局控件:

使用网格布局(grid)或包装布局(pack)来安排控件的位置。例如,使用网格布局将标签和按钮放置在窗口中:

label.grid(row=0, column=0)

button.grid(row=1, column=0)

运行主循环:

root.mainloop()

完整代码:

import tkinter as tk

# 创建主窗口

window = tk.Tk()

window.title("GUI编程示例")

# 创建标签

label = tk.Label(window, text="欢迎来到GUI编程!", font=("Arial", 16))code>

label.pack()

# 创建按钮

button = tk.Button(window, text="点击我!", command=lambda: print("你点击了按钮!"))code>

button.pack()

# 运行主循环

window.mainloop()

2、PyQt简单使用

PyQt 是 Python 中常用的 GUI 编程库,用于创建图形用户界面。下面是 PyQt 的简单使用说明:

导入 PyQt 模块:

from PyQt5 import QtWidgets

创建应用程序对象:

app = QtWidgets.QApplication([])

创建主窗口:

window = QtWidgets.QMainWindow()

添加控件:

可以添加各种控件,如标签、按钮、文本框等。例如,添加一个标签和一个按钮:

label = QtWidgets.QLabel("Hello, PyQt!")

button = QtWidgets.QPushButton("Click me!")

设置布局:

使用布局管理器来安排控件的位置和大小。常用的布局管理器有 QVBoxLayout、QHBoxLayout、QGridLayout 等。例如,使用 QVBoxLayout 将标签和按钮放置在窗口中:

layout = QtWidgets.QVBoxLayout()

layout.addWidget(label)

layout.addWidget(button)

将布局设置给主窗口:

central_widget = QtWidgets.QWidget()

central_widget.setLayout(layout)

window.setCentralWidget(central_widget)

显示窗口:

window.show()

运行应用程序的主循环:

app.exec_()

完整代码:

from PyQt5 import QtWidgets

# 创建应用程序

app = QtWidgets.QApplication([])

# 创建主窗口

window = QtWidgets.QWidget()

window.setWindowTitle("GUI编程示例")

# 创建标签

label = QtWidgets.QLabel("欢迎来到GUI编程!")

label.setFont(QtWidgets.QFont("Arial", 16))

# 创建按钮

button = QtWidgets.QPushButton("点击我!")

button.clicked.connect(lambda: print("你点击了按钮!"))

# 创建布局

layout = QtWidgets.QVBoxLayout()

layout.addWidget(label)

layout.addWidget(button)

# 设置主窗口布局

window.setLayout(layout)

# 显示主窗口

window.show()

# 运行应用程序

app.exec_()

3、wxPython简单使用

wxPython 是 Python 中常用的 GUI 编程库,用于创建图形用户界面。下面是 wxPython 的简单使用说明:

导入 wxPython 模块:

import wx

创建应用程序对象:

app = wx.App()

创建顶级窗口:

frame = wx.Frame(None, title="Hello, wxPython!")code>

添加控件:

可以添加各种控件,如标签、按钮、文本框等。例如,添加一个标签和一个按钮:

panel = wx.Panel(frame)

label = wx.StaticText(panel, label="Hello, wxPython!")code>

button = wx.Button(panel, label="Click me!")code>

设置布局:

使用布局管理器来安排控件的位置和大小。常用的布局管理器有 BoxSizer、GridSizer、FlexGridSizer 等。例如,使用 BoxSizer 将标签和按钮放置在窗口中:

sizer = wx.BoxSizer(wx.VERTICAL)

sizer.Add(label, 0, wx.ALL, 10)

sizer.Add(button, 0, wx.ALL, 10)

panel.SetSizer(sizer)

显示窗口:

frame.Show()

运行应用程序的主循环:

app.MainLoop()

完整代码:

import wx

# 创建应用程序

app = wx.App()

# 创建主窗口

frame = wx.Frame(None, title="GUI编程示例")code>

# 创建面板

panel = wx.Panel(frame)

# 创建标签

label = wx.StaticText(panel, label="欢迎来到GUI编程!", pos=(50, 50))code>

label.SetFont(wx.Font(16, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL))

# 创建按钮

button = wx.Button(panel, label="点击我!", pos=(50, 100))code>

button.Bind(wx.EVT_BUTTON, lambda event: print("你点击了按钮!"))

# 显示主窗口

frame.Show()

# 运行应用程序

app.MainLoop()

二、Tkinter、PyQt和wxPython库实现计算器

1、Tkinter实现计算器

import tkinter as tk

def calculate():

expression = entry.get()

try:

result = eval(expression)

result_label.config(text="结果: " + str(result))code>

except:

result_label.config(text="无效的表达式")code>

def clear():

entry.delete(0, tk.END)

result_label.config(text="结果:")code>

window = tk.Tk()

window.title("复杂计算器")

entry = tk.Entry(window, width=30)

entry.pack()

button_frame = tk.Frame(window)

button_frame.pack()

calculate_button = tk.Button(button_frame, text="计算", command=calculate)code>

calculate_button.grid(row=0, column=0)

clear_button = tk.Button(button_frame, text="清除", command=clear)code>

clear_button.grid(row=0, column=1)

result_label = tk.Label(window, text="结果:")code>

result_label.pack()

window.mainloop()

2、PyQt实现计算器

from PyQt5 import QtWidgets

class Calculator(QtWidgets.QWidget):

def __init__(self):

super().__init__()

self.setWindowTitle("复杂计算器")

self.layout = QtWidgets.QVBoxLayout()

self.entry = QtWidgets.QLineEdit()

self.layout.addWidget(self.entry)

button_frame = QtWidgets.QWidget()

button_layout = QtWidgets.QHBoxLayout(button_frame)

self.layout.addWidget(button_frame)

calculate_button = QtWidgets.QPushButton("计算")

calculate_button.clicked.connect(self.calculate)

button_layout.addWidget(calculate_button)

clear_button = QtWidgets.QPushButton("清除")

clear_button.clicked.connect(self.clear)

button_layout.addWidget(clear_button)

self.result_label = QtWidgets.QLabel("结果:")

self.layout.addWidget(self.result_label)

self.setLayout(self.layout)

def calculate(self):

expression = self.entry.text()

try:

result = eval(expression)

self.result_label.setText("结果: " + str(result))

except:

self.result_label.setText("无效的表达式")

def clear(self):

self.entry.clear()

self.result_label.setText("结果:")

app = QtWidgets.QApplication([])

calculator = Calculator()

calculator.show()

app.exec_()

3、wxPython实现计算器

import wx

class CalculatorFrame(wx.Frame):

def __init__(self):

super().__init__(parent=None, title="复杂计算器")code>

self.panel = wx.Panel(self)

self.entry = wx.TextCtrl(self.panel)

self.calculate_button = wx.Button(self.panel, label="计算")code>

self.clear_button = wx.Button(self.panel, label="清除")code>

self.result_label = wx.StaticText(self.panel, label="结果:")code>

self.calculate_button.Bind(wx.EVT_BUTTON, self.calculate)

self.clear_button.Bind(wx.EVT_BUTTON, self.clear)

sizer = wx.BoxSizer(wx.VERTICAL)

sizer.Add(self.entry, proportion=1, flag=wx.EXPAND)

sizer.Add(self.calculate_button, flag=wx.EXPAND)

sizer.Add(self.clear_button, flag=wx.EXPAND)

sizer.Add(self.result_label, flag=wx.EXPAND)

self.panel.SetSizer(sizer)

def calculate(self, event):

expression = self.entry.GetValue()

try:

result = eval(expression)

self.result_label.SetLabel("结果: " + str(result))

except:

self.result_label.SetLabel("无效的表达式")

def clear(self, event):

self.entry.Clear()

self.result_label.SetLabel("结果:")

app = wx.App()

frame = CalculatorFrame()

frame.Show()

app.MainLoop()

三、Tkinter、PyQt和wxPython库简单QQ聊天

1、Tkinter实现QQ聊天

import tkinter as tk

def send_message():

message = entry.get()

# 发送消息的逻辑处理

print("发送消息:", message)

entry.delete(0, tk.END)

window = tk.Tk()

window.title("QQ聊天系统")

window.geometry("400x300")

message_box = tk.Text(window)

message_box.pack(pady=10)

entry = tk.Entry(window)

entry.pack(pady=10)

send_button = tk.Button(window, text="发送", command=send_message)code>

send_button.pack()

window.mainloop()

2、PyQt实现QQ聊天

from PyQt5 import QtWidgets

def send_message():

message = entry.text()

# 发送消息的逻辑处理

print("发送消息:", message)

entry.clear()

app = QtWidgets.QApplication([])

window = QtWidgets.QWidget()

window.setWindowTitle("QQ聊天系统")

window.setGeometry(100, 100, 400, 300)

message_box = QtWidgets.QTextEdit(window)

message_box.setGeometry(10, 10, 380, 200)

entry = QtWidgets.QLineEdit(window)

entry.setGeometry(10, 220, 300, 30)

send_button = QtWidgets.QPushButton(window, text="发送")code>

send_button.setGeometry(320, 220, 60, 30)

send_button.clicked.connect(send_message)

window.show()

app.exec_()

3、wxPython实现QQ聊天

import wx

class ChatWindow(wx.Frame):

def __init__(self):

super().__init__(None, title="QQ聊天系统", size=(400, 300))code>

panel = wx.Panel(self)

sizer = wx.BoxSizer(wx.VERTICAL)

self.message_box = wx.TextCtrl(panel, style=wx.TE_MULTILINE)

sizer.Add(self.message_box, 1, wx.EXPAND | wx.ALL, 10)

self.entry = wx.TextCtrl(panel)

sizer.Add(self.entry, 0, wx.EXPAND | wx.ALL, 10)

send_button = wx.Button(panel, label="发送")code>

sizer.Add(send_button, 0, wx.ALIGN_CENTER | wx.ALL, 10)

send_button.Bind(wx.EVT_BUTTON, self.send_message)

panel.SetSizer(sizer)

self.Show()

def send_message(self, event):

message = self.entry.GetValue()

# 发送消息的逻辑处理

print("发送消息:", message)

self.entry.Clear()

app = wx.App()

ChatWindow()

app.MainLoop()

四、Tkinter、PyQt和wxPython库贪吃蛇游戏

1、Tkinter实现贪吃蛇游戏

import tkinter as tk

import random

WIDTH = 400

HEIGHT = 400

DELAY = 100

DOT_SIZE = 20

class SnakeGame(tk.Canvas):

def __init__(self, master):

super().__init__(master, width=WIDTH, height=HEIGHT, background="black")code>

self.snake = [(100, 100), (80, 100), (60, 100)]

self.direction = "Right"

self.food = self.create_food()

self.score = 0

self.bind_all("<Key>", self.on_key_press)

self.pack()

self.after(DELAY, self.move_snake)

def create_food(self):

x = random.randint(1, (WIDTH-DOT_SIZE) / DOT_SIZE) * DOT_SIZE

y = random.randint(1, (HEIGHT-DOT_SIZE) / DOT_SIZE) * DOT_SIZE

return self.create_oval(x, y, x+DOT_SIZE, y+DOT_SIZE, fill="white")code>

def move_snake(self):

head_x, head_y = self.snake[0]

if self.direction == "Right":

new_head = (head_x + DOT_SIZE, head_y)

elif self.direction == "Left":

new_head = (head_x - DOT_SIZE, head_y)

elif self.direction == "Up":

new_head = (head_x, head_y - DOT_SIZE)

else:

new_head = (head_x, head_y + DOT_SIZE)

self.snake.insert(0, new_head)

if self.check_collision():

self.game_over()

else:

self.delete(self.snake[-1])

if self.snake[0] == self.food:

self.score += 1

self.create_food()

else:

self.snake.pop()

for x, y in self.snake:

self.create_rectangle(x, y, x+DOT_SIZE, y+DOT_SIZE, fill="green")code>

self.after(DELAY, self.move_snake)

def check_collision(self):

head_x, head_y = self.snake[0]

return (

head_x < 0 or

head_x >= WIDTH or

head_y < 0 or

head_y >= HEIGHT or

(head_x, head_y) in self.snake[1:]

)

def game_over(self):

self.delete(tk.ALL)

self.create_text(

WIDTH/2, HEIGHT/2,

text=f"Game Over! Score: {self.score}",

fill="white",code>

font=("Arial", 20),

)

def on_key_press(self, event):

key = event.keysym

if key == "Right" and self.direction != "Left":

self.direction = "Right"

elif key == "Left" and self.direction != "Right":

self.direction = "Left"

elif key == "Up" and self.direction != "Down":

self.direction = "Up"

elif key == "Down" and self.direction != "Up":

self.direction = "Down"

root = tk.Tk()

root.title("Snake Game")

snake_game = SnakeGame(root)

root.mainloop()

2、PyQt实现贪吃蛇游戏

from PyQt5 import QtWidgets, QtCore, QtGui

import random

WIDTH = 400

HEIGHT = 400

DELAY = 100

DOT_SIZE = 20

class SnakeGame(QtWidgets.QWidget):

def __init__(self):

super().__init__()

self.snake = [(100, 100), (80, 100), (60, 100)]

self.direction = "Right"

self.food = self.create_food()

self.score = 0

self.timer = QtCore.QTimer(self)

self.timer.timeout.connect(self.move_snake)

self.timer.start(DELAY)

self.setWindowTitle("贪吃蛇游戏")

self.setGeometry(100, 100, WIDTH, HEIGHT)

self.show()

def paintEvent(self, event):

qp = QtGui.QPainter()

qp.begin(self)

self.draw_snake(qp)

self.draw_food(qp)

qp.end()

def draw_snake(self, qp):

qp.setBrush(QtGui.QColor(0, 255, 0))

for x, y in self.snake:

qp.drawRect(x, y, DOT_SIZE, DOT_SIZE)

def draw_food(self, qp):

qp.setBrush(QtGui.QColor(255, 255, 255))

qp.drawEllipse(*self.food, DOT_SIZE, DOT_SIZE)

def create_food(self):

x = random.randint(1, (WIDTH-DOT_SIZE) / DOT_SIZE) * DOT_SIZE

y = random.randint(1, (HEIGHT-DOT_SIZE) / DOT_SIZE) * DOT_SIZE

return (x, y)

def move_snake(self):

head_x, head_y = self.snake[0]

if self.direction == "Right":

new_head = (head_x + DOT_SIZE, head_y)

elif self.direction == "Left":

new_head = (head_x - DOT_SIZE, head_y)

elif self.direction == "Up":

new_head = (head_x, head_y - DOT_SIZE)

else:

new_head = (head_x, head_y + DOT_SIZE)

self.snake.insert(0, new_head)

if self.check_collision():

self.game_over()

else:

self.snake.pop()

if self.snake[0] == self.food:

self.score += 1

self.create_food()

self.update()

def check_collision(self):

head_x, head_y = self.snake[0]

return (

head_x < 0 or

head_x >= WIDTH or

head_y < 0 or

head_y >= HEIGHT or

(head_x, head_y) in self.snake[1:]

)

def game_over(self):

self.timer.stop()

QtWidgets.QMessageBox.information(self, "游戏结束", f"游戏结束!得分: {self.score}")

def keyPressEvent(self, event):

key = event.key()

if key == QtCore.Qt.Key_Right and self.direction != "Left":

self.direction = "Right"

elif key == QtCore.Qt.Key_Left and self.direction != "Right":

self.direction = "Left"

elif key == QtCore.Qt.Key_Up and self.direction != "Down":

self.direction = "Up"

elif key == QtCore.Qt.Key_Down and self.direction != "Up":

self.direction = "Down"

app = QtWidgets.QApplication([])

snake_game = SnakeGame()

app.exec_()```

## 3、wxPython实现贪吃蛇游戏

```csharp

import wx

import random

WIDTH = 400

HEIGHT = 400

DELAY = 100

DOT_SIZE = 20

class SnakeGame(wx.Frame):

def __init__(self):

super().__init__(None, title="贪吃蛇游戏", size=(WIDTH, HEIGHT))code>

self.snake = [(100, 100), (80, 100), (60, 100)]

self.direction = "Right"

self.food = self.create_food()

self.score = 0

self.timer = wx.Timer(self)

self.Bind(wx.EVT_TIMER, self.move_snake, self.timer)

self.timer.Start(DELAY)

self.Bind(wx.EVT_PAINT, self.on_paint)

self.Bind(wx.EVT_KEY_DOWN, self.on_key_down)

self.Centre()

self.Show()

def on_paint(self, event):

dc = wx.PaintDC(self)

self.draw_snake(dc)

self.draw_food(dc)

def draw_snake(self, dc):

dc.SetBrush(wx.Brush(wx.Colour(0, 255, 0)))

for x, y in self.snake:

dc.DrawRectangle(x, y, DOT_SIZE, DOT_SIZE)

def draw_food(self, dc):

dc.SetBrush(wx.Brush(wx.Colour(255, 255, 255)))

dc.DrawCircle(*self.food, DOT_SIZE//2)

def create_food(self):

x = random.randint(1, (WIDTH-DOT_SIZE) // DOT_SIZE) * DOT_SIZE

y = random.randint(1, (HEIGHT-DOT_SIZE) // DOT_SIZE) * DOT_SIZE

return (x, y)

def move_snake(self, event):

head_x, head_y = self.snake[0]

if self.direction == "Right":

new_head = (head_x + DOT_SIZE, head_y)

elif self.direction == "Left":

new_head = (head_x - DOT_SIZE, head_y)

elif self.direction == "Up":

new_head = (head_x, head_y - DOT_SIZE)

else:

new_head = (head_x, head_y + DOT_SIZE)

self.snake.insert(0, new_head)

if self.check_collision():

self.game_over()

else:

self.snake.pop()

if self.snake[0] == self.food:

self.score += 1

self.food = self.create_food()

self.Refresh()

def check_collision(self):

head_x, head_y = self.snake[0]

return (

head_x < 0 or

head_x >= WIDTH or

head_y < 0 or

head_y >= HEIGHT or

(head_x, head_y) in self.snake[1:]

)

def game_over(self):

self.timer.Stop()

wx.MessageBox(f"游戏结束!得分: {self.score}", "游戏结束")

self.Close()

def on_key_down(self, event):

key_code = event.GetKeyCode()

if key_code == wx.WXK_RIGHT and self.direction != "Left":

self.direction = "Right"

elif key_code == wx.WXK_LEFT and self.direction != "Right":

self.direction = "Left"

elif key_code == wx.WXK_UP and self.direction != "Down":

self.direction = "Up"

elif key_code == wx.WXK_DOWN and self.direction != "Up":

self.direction = "Down"

app = wx.App()

SnakeGame()

app.MainLoop()

总结

Python的GUI编程和图形界面设计相对简单易学,适用于各种应用程序的开发,包括桌面应用、游戏、数据可视化等。通过使用Python的GUI编程,开发者可以快速地创建功能强大、用户友好的图形界面应用程序。



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。