猫史档案馆


【windows系统】python

用户:不起眼的账号不起眼的账号查看: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() # 更新整个窗口


回复

上一页1 页 / 共 1下一页
CRP_辞旧CRP_辞旧

我..***

点赞0


评论


土土er土土er

是你写的代码吗,好厉害

点赞0


评论


不起眼的账号不起眼的账号

我一般用pygame,pygame比较高级点

点赞0


评论


不起眼的账号不起眼的账号

配置差的最好别进,那个关机我电脑黑了0.02秒屏就结束了,配置低可能会比较高延迟关闭

点赞0


评论