用户:
不起眼的账号查看:3 回复:4 评论:3 创建时间:2020-05-16T12:14:15
别怪我吓到了,开始菜单关机停止
import pygame
from pygame.locals import *
import time
import sys
pygame.init()
screen_size = (
pygame.display.Info().current_w,
pygame.display.Info().current_h
) # 自动测量分辨率,N不NB🤣
window_catching = None # 正在移动的窗口
offset = None # 移动误差
screen = pygame.display.set_mode(screen_size,FULLSCREEN) # FULLSCREEN代表全屏,此时的screen_size表示分辨率
pygame.display.set_caption("虚拟系统") # 标题
import os
# os.name是有两种情况:nt:Windows,posix:Linux / MacOS
if os.name == "nt":
font = pygame.font.SysFont("SimHei",20)
else:
font = pygame.font.SysFont("heittf",20)
del os # 清理一下,把os库删除导入
class w_rect(pygame.Rect): # rect类的一个衍生类,有一个新的属性:win
win = None
# window类,表示窗口
class Window:
def __init__(self,size,title="",movable=True,layout={}):
self.start_win = False
self.size = size
self.top = False
self.movable = movable
self.left_top_pos = (
int(screen_size[0] / 2 - size[0] / 2),
int(screen_size[1] / 2 - size[1] / 2)
)
self.layout = layout
self.title_txt = title
self.hide = False
self.__build()
def __build(self): # 私有方法,别人无法访问,用于创建动态信息
self.position = [self.left_top_pos,
(self.left_top_pos[0] + self.size[0],
self.left_top_pos[1] + self.size[1])]
self.title = pygame.Rect(self.position[0][0],
self.position[0][1] - 20,
self.size[0],
20)
self.button_close = pygame.Rect(self.position[0][0] + self.size[0] - 20,
self.position[0][1] - 20,
20,
20)
self.button_hide = pygame.Rect(self.position[0][0] + self.size[0] - 40,
self.position[0][1] - 20,
20,
20)
self.body = pygame.Rect(self.position[0][0],
self.position[0][1],
self.size[0],
self.size[1])
def draw(self,screen): # 绘制窗口
self.__build()
pygame.draw.rect(screen,0xFFFFFF,self.body)
pygame.draw.rect(screen,0x000000,self.body,1)
if self.top:
pygame.draw.rect(screen,0x0000FF,self.title)
self.top = False
else:
pygame.draw.rect(screen,0xFFFFFF,self.title)
pygame.draw.rect(screen,0x000000,self.title,1)
pygame.draw.rect(screen,0xFF0000,self.button_close)
pygame.draw.rect(screen,0x00FF00,self.button_hide)
screen.blit(font.render("×",True,(0,0,0)),self.button_close)
screen.blit(font.render("-",True,(0,0,0)),self.button_hide)
screen.blit(font.render(self.title_txt,True,(0,0,0)),self.title)
for pos in self.layout:
self.layout[pos].draw((self.position[0][0] + pos[0],
self.position[0][1] + pos[1]),screen)
def move(self,offset,pos): # 当该窗口是movable时,移动窗口
if self.movable:
self.left_top_pos = (pos[0] - offset[0],pos[1] - offset[1])
def click(self,pos,windows): # 检测鼠标事件
if self.button_close.collidepoint(pos):
windows.remove(self)
if self.button_hide.collidepoint(pos):
self.hide = True
for key in self.layout:
self.layout[key].check(pos)
# start类,表示开始菜单
# 结构同上
class Start:
def __init__(self):
self.__build()
def __build(self):
self.rect = pygame.Rect(0,screen_size[1] - 20,
screen_size[0],20)
self.button = pygame.Rect(0,screen_size[1] - 20,
100,20)
self.win_rects = []
def draw(self,screen,windows):
self.__build()
pygame.draw.rect(screen,0x000000,self.rect)
pygame.draw.rect(screen,0x00FF00,self.button)
screen.blit(font.render("开始",True,(255,255,255)),self.button)
x = 100
y = screen_size[1] - 20
for w in set(windows):
rect = w_rect(x,y,150,20)
rect.win = w
self.win_rects.append(rect)
pygame.draw.rect(screen,0x0000FF,rect)
pygame.draw.rect(screen,0x000000,rect,1)
screen.blit(font.render(w.title_txt,True,(0,0,0)),rect)
x += 150
def click(self,pos):
global windows
if self.button.collidepoint(pos):
for w in windows:
if w.start_win:
windows.remove(w)
break
else:
win = Window((200,200),title="开始菜单")
win.start_win = True
win.left_top_pos = (0,screen_size[1] - 220)
win.layout = {
(0,0):Button("关机",(255,0,0),(200,50),shutdown),
(0,50):Button("hello",(230,230,230),(200,50),app_hello),
(0,100):Button("date",(230,230,230),(200,50),app_date),
(0,150):Button("info",(230,230,230),(200,50),app_info)
}
win.movable = False
windows.append(win)
for rect in self.win_rects:
if rect.collidepoint(pos):
win = rect.win
if win == windows[0]:
win.hide = not win.hide
else:
win.hide = False
windows.remove(win)
windows = [win] + windows
# 按钮类,可以依附于窗口或独立存在
# 结构同上
class Button:
def __init__(self,label,color,size,command):
self.label = label
self.color = color
self.size = size
self.run = command
def __build(self,pos):
self.rect = pygame.Rect(pos[0],pos[1],self.size[0],self.size[1])
def draw(self,pos,screen):
self.__build(pos)
pygame.draw.rect(screen,self.color,self.rect)
pygame.draw.rect(screen,0x000000,self.rect,1)
screen.blit(font.render(self.label,True,(0,0,0)),self.rect)
def check(self,pos):
if self.rect.collidepoint(pos):
self.run()
# 应用类,可以自己写应用
# 其实是一个数据固定的按钮
# 结构依然同上-_-
class Application:
def __init__(self,label,command):
self.label = "应用:"+label
self.color = 0xCFCFCF
self.size = (150,30)
self.run = command
def __build(self,pos):
self.rect = pygame.Rect(pos[0],pos[1],self.size[0],self.size[1])
def draw(self,pos,screen):
self.__build(pos)
pygame.draw.rect(screen,self.color,self.rect)
screen.blit(font.render(self.label,True,(0,0,0)),self.rect)
def check(self,pos):
if self.rect.collidepoint(pos):
self.run()
# 标签类,用于显示字符,可以依附于窗口
# 结构同上……
class Label:
def __init__(self,label,color,size):
self.label = label
self.color = color
self.size = size
def __build(self,pos):
self.rect = pygame.Rect(pos[0],pos[1],self.size[0],self.size[1])
def draw(self,pos,screen):
self.__build(pos)
pygame.draw.rect(screen,self.color,self.rect)
pygame.draw.rect(screen,0x000000,self.rect,1)
screen.blit(font.render(self.label,True,(0,0,0)),self.rect)
def check(self,pos):...
# 为了date应用,从Label衍生出的一个date类
# 主要不同:可以根据时间动态变换
class Date(Label):
def __init__(self, label, color, size):
return super().__init__(label, color, size)
def draw(self,pos,screen):
self.__build(pos)
pygame.draw.rect(screen,self.color,self.rect)
pygame.draw.rect(screen,0x000000,self.rect,1)
screen.blit(font.render(time.strftime(self.label,time.localtime(time.time())),True,(0,0,0)),self.rect)
def __build(self,pos):
self.rect = pygame.Rect(pos[0],pos[1],self.size[0],self.size[1])
# “关机”函数,其实就是退出程序
def shutdown():
pygame.quit()
sys.exit()
# app_info应用中一个按钮的执行程序
def massage():
windows.append(
Window(
(200,10),
"Info",
layout={
(0,0) :Label(
"Hello!这是一条信息",
0xFFFFFF,
(200,20)
)
}
)
)
# helloworld程序
def app_hello():
windows.append(
Window(
(200,200),
"Hello world!",
layout={
(0,0) :Label(
"Hello world!",
0xFFFFFF,
(200,200)
)
}
)
)
# date程序
def app_date():
windows.append(
Window(
(200,20),
"Date",
layout={
(0,0) :Date(
"%Y-%m-%d %H:%M:%S",
0xFFFFFF,
(200,20)
)
}
)
)
# 创建新窗口的程序
def app_info():
windows.append(
Window(
(100,100),
"Info",
layout={
(0,0) :Button(
"按我",
0xEFEFEF,
(100,100),
massage
)
}
)
)
# 以下主程序
windows = [] # 所有窗口
apps = [
Application("hello",app_hello),
Application("Date",app_date),
Application("info",app_info)
] # 所有程序
start = Start() # 开始菜单
bg = pygame.transform.scale(pygame.image.load("bg.jpg"),screen_size) # 背景图片
# 主循环
while True:
screen.blit(bg,(0,0)) # 绘制背景
start.draw(screen,windows)
# 以下绘制应用
app_x = 0
app_y = 0
for app in apps:
app.draw((app_x,app_y),screen)
app_y += 35
# 以下绘制窗口
for win_index in range(len(windows)):
win = windows[::-1][win_index]
if not win.hide:
if win_index == len(windows) - 1:
win.top = True
win.draw(screen)
# 这个应该很熟悉
for event in pygame.event.get():
if event.type == QUIT: # 关机
shutdown()
if event.type == MOUSEBUTTONDOWN:
if event.button == BUTTON_LEFT:
# 以下检测窗口事件
for win in windows:
if not win.hide:
if win.body.collidepoint(event.pos) or win.title.collidepoint(event.pos):
if win.title.collidepoint(event.pos):
window_catching = win
offset = (event.pos[0] - win.left_top_pos[0],event.pos[1] - win.left_top_pos[1])
windows.remove(win)
windows = [win] + windows
win.click(event.pos,windows)
break
else:
# 以下检测其他事件
start.click(event.pos)
for app in apps:
app.check(event.pos)
if event.type == MOUSEBUTTONUP:
# 松开窗口
if event.button == BUTTON_LEFT:
window_catching = None
offset = None
if event.type == MOUSEMOTION:
# 移动窗口
if window_catching:
window_catching.move(offset,event.pos)
pygame.display.flip() # 更新整个窗口