首页 > 其他分享 >pygame封装常用控件,第二日,有滑块的文本显示域

pygame封装常用控件,第二日,有滑块的文本显示域

时间:2024-08-29 14:49:11浏览次数:7  
标签:控件 滑块 text self height width pygame collbar 哈哈哈

#coding=utf-8

import os,sys,re,time
import pygame
import random
from win32api import GetSystemMetrics
from tkinter import messagebox

pygame.init()
pygame.display.set_caption("我的控件")

percent = 0.6
screen_width = GetSystemMetrics(0)
screen_height = GetSystemMetrics(1)
window_width = int(screen_width*percent)
window_height = int(screen_height*percent)

dt = 0
clock = pygame.time.Clock()

screen = pygame.display.set_mode((window_width, window_height))

#停止处理输入法事件
pygame.key.stop_text_input()

def showMsg(msg):
    messagebox.showinfo('提示信息', msg)

class Button:
    def __init__(self, x, y, w, h):
        self.x = x
        self.y = y
        self.w = w
        self.h = h
        self.color = 'gray'
        self.text = '按钮'
        self.text_color = 'black'
        self.text_size = 12
        self.border_width = 1
        self.border_color = 'black'
        self.font_path = os.path.join(os.path.dirname(sys.argv[0]), 'simsun.ttc')
        self.my_font = pygame.font.Font(self.font_path, self.text_size)
        
    def setColor(self, color):
        self.color = color
        
    def setText(self, text):
        self.text = text
        
    def getText(self):
        return self.text
        
    def setTextColor(self, text_color):
        self.text_color = text_color
        
    def setTextSize(self, text_size):
        self.text_size = text_size
        self.my_font = pygame.font.Font(self.font_path, self.text_size)
        
    def setBorderWidth(self, border_width):
        self.border_width = border_width
        
    def setBorderColor(self, border_color):
        self.border_color = border_color
        
    def draw(self, win):
        
        pygame.draw.rect(win, self.color, (self.x, self.y, self.w, self.h))
        if self.border_width > 0:
            pygame.draw.rect(win, self.border_color, (self.x, self.y, self.w, self.h), self.border_width)
            
        text = self.my_font.render(self.text, True, self.text_color)
        myx = self.x + (self.w - text.get_width()) / 2
        myy = self.y + (self.h - text.get_height()) / 2
        win.blit(text, (myx, myy))
        
    def click(self, event):
        if event.type == pygame.MOUSEBUTTONDOWN:
            if self.x + self.w > event.pos[0] > self.x and self.y + self.h > event.pos[1] > self.y:
                return True
        return False
    
class Label:
    def __init__(self, x, y, w, h):
        self.x = x
        self.y = y
        self.w = w
        self.h = h
        self.color = 'white'
        self.text = ''
        self.text_color = 'black'
        self.text_size = 12
        self.border_width = 0
        self.border_color = ''
        self.font_path = os.path.join(os.path.dirname(sys.argv[0]), 'simsun.ttc')
        self.my_font = pygame.font.Font(self.font_path, self.text_size)
        
    def setColor(self, color):
        self.color = color
        
    def setText(self, text):
        self.text = text
        
    def getText(self):
        return self.text
        
    def setTextColor(self, text_color):
        self.text_color = text_color
        
    def setTextSize(self, text_size):
        self.text_size = text_size
        self.my_font = pygame.font.Font(self.font_path, self.text_size)
        
    def setBorderWidth(self, border_width):
        self.border_width = border_width
        
    def setBorderColor(self, border_color):
        self.border_color = border_color
        
    def getCharWH(self):
        padding_percent_width = 0.3
        padding_percent_height = 0.3
        test_text1 = '测试字符串'
        test_text2 = self.my_font.render(test_text1, True, self.text_color)
        char_width = test_text2.get_width() / len(test_text1)
        char_height = test_text2.get_height()
        padding_width = char_width * padding_percent_width
        padding_height = char_height * padding_percent_height
        max_field_num = int((self.w - padding_width * 2) / char_width)
        
        return (char_height, padding_width, padding_height, max_field_num)
    
    def getTrueLines(self, max_field_num):
        texts = self.text.split("\n")
        k = 0
        for i,mytext in enumerate(texts):
            while len(mytext) > max_field_num:
                submytext = mytext[0:max_field_num]
                mytext = mytext[max_field_num:]
                k += 1
            k += 1
        return k+1
        
    def draw(self, win):
        (char_height, padding_width, padding_height, max_field_num) = self.getCharWH()
        lineNum = self.getTrueLines(max_field_num)
        if lineNum * char_height > self.h:
            self.h = lineNum * char_height
            
        pygame.draw.rect(win, self.color, (self.x, self.y, self.w, self.h))
        if self.border_width > 0:
            pygame.draw.rect(win, self.border_color, (self.x, self.y, self.w, self.h), self.border_width)
        
        texts = self.text.split("\n")
        k = 0
        for i,mytext in enumerate(texts):
            while len(mytext) > max_field_num:
                submytext = mytext[0:max_field_num]
                
                subtext = self.my_font.render(submytext, True, self.text_color)
                submyx = self.x + padding_width
                submyy = self.y + padding_height + char_height * k
                win.blit(subtext, (submyx, submyy))
                
                mytext = mytext[max_field_num:]
                k += 1
            
            text = self.my_font.render(mytext, True, self.text_color)
            myx = self.x + padding_width
            myy = self.y + padding_height + char_height * k
            win.blit(text, (myx, myy))
            k += 1
    
class TextArea:
    startx = 0
    endx = 0
    
    starty = 0
    endy = 0
    
    padding_width = 0
    padding_height = 0
    char_width = 0
    char_height = 0
    
    max_field_num = 0
    
    collbar_color = 'gray'
    collbar_bgcolor = 'lightgray'
    
    collbar_width_x = 0
    collbar_height_x = 5
    collbar_offset_x = 0
    collbar_percent_x = 0
    dragging_x = False
    
    collbar_width_y = 5
    collbar_height_y = 0
    collbar_offset_y = 0
    collbar_percent_y = 0
    dragging_y = False
    
    line_wrap = False
    
    def __init__(self, x, y, w, h, text, text_size = 12):
        self.x = x
        self.y = y
        self.w = w
        self.h = h
        self.color = 'white'
        self.text = text
        self.text_color = 'black'
        self.text_size = text_size
        self.border_width = 0
        self.border_color = ''
        self.font_path = os.path.join(os.path.dirname(sys.argv[0]), 'simsun.ttc')
        self.my_font = pygame.font.Font(self.font_path, self.text_size)
        
        self.getCharWH()
        
    def setColor(self, color):
        self.color = color
        
    def setText(self, text):
        self.text = text
        self.getCharWH()
        
    def getText(self):
        return self.text
        
    def setTextColor(self, text_color):
        self.text_color = text_color
        
    def setTextSize(self, text_size):
        self.text_size = text_size
        self.my_font = pygame.font.Font(self.font_path, self.text_size)
        self.getCharWH()
        
    def setBorderWidth(self, border_width):
        self.border_width = border_width
        
    def setBorderColor(self, border_color):
        self.border_color = border_color
        
    def getCharWH(self):
        padding_percent_width = 0.3
        padding_percent_height = 0.3
        test_text1 = '测试字符串'
        test_text2 = self.my_font.render(test_text1, True, self.text_color)
        
        self.char_width = test_text2.get_width() / len(test_text1)
        self.char_height = test_text2.get_height()
        self.padding_width = self.char_width * padding_percent_width
        self.padding_height = self.char_height * padding_percent_height
        
        self.max_field_num = self.getMaxFieldNum()
        showLineNum = self.getShowLineNum()
        totalLineNum = self.getTotalLineNum()
        print(showLineNum)
        print(totalLineNum)
        print()
        self.collbar_percent_y = showLineNum / totalLineNum

        if totalLineNum * self.char_height + 2 * self.padding_height+self.collbar_height_x > self.h:
            self.collbar_height_y = self.collbar_percent_y * (self.h - self.padding_height * 2-self.collbar_height_x)
        
        showFieldNum = self.getShowFieldNum()
        totalFieldNum = self.getTotalFieldNum()
        self.collbar_percent_x = showFieldNum / totalFieldNum
        if totalFieldNum * self.char_width + 2 * self.padding_width+self.collbar_width_y > self.w:
            self.collbar_width_x = self.collbar_percent_x * (self.w - self.padding_width * 2-self.collbar_width_y)
    
    #计算每行多少个字
    def getMaxFieldNum(self):
        num = 0
        if self.line_wrap == True:
            #折行时按控件宽度计算
            num = int((self.w - self.padding_width * 2 - self.collbar_width_y) / self.char_width)
        else:
            #不折行时按最长的行所含字符算
            texts = self.text.split("\n")
            for text in texts:
                if len(text) > num:
                    num = len(text)
        return num
    
    #计算可以一次性展示的行数
    def getShowLineNum(self):
        lostHeight = self.h - 2 * self.padding_height;
        num = int(lostHeight // self.char_height)
        return num
    
    #计算所有行数
    def getTotalLineNum(self):
        texts = self.text.split("\n")
        if self.line_wrap == True:
            k = 0
            for i,mytext in enumerate(texts):
                while len(mytext) > self.max_field_num:
                    submytext = mytext[0:self.max_field_num]
                    mytext = mytext[self.max_field_num:]
                    k += 1
                k += 1
            return k
        else:
            return len(texts)
    
    #计算可以一次性展示的列数
    def getShowFieldNum(self):
        lostWidth = self.w - 2 * self.padding_width - self.collbar_width_y;
        num = int(lostWidth // self.char_width)
        return num
    
    #计算最长的行的列数
    def getTotalFieldNum(self):
        num = 0
        if self.line_wrap == True:
            #折行时按控件宽度计算
            num = int((self.w - self.padding_width * 2 - self.collbar_width_y) / self.char_width)
        else:
            #不折行时按最长的行所含字符算
            texts = self.text.split("\n")
            for text in texts:
                if len(text) > num:
                    num = len(text)
        return num
    
    def getTrueLineTexts(self):
        res = []
        texts = self.text.split("\n")
        k = 0
        for i,mytext in enumerate(texts):
            while len(mytext) > self.max_field_num:
                submytext = mytext[0:self.max_field_num]
                res.append(submytext)
                mytext = mytext[self.max_field_num:]
                k += 1
            k += 1
            res.append(mytext)
        return res
    
    def draggingyMe(self, event):
        if event.type == pygame.MOUSEBUTTONDOWN:
            if self.x + self.w > event.pos[0] > self.x and self.y + self.h > event.pos[1] > self.y:
                self.dragging_x = True
                self.startx = event.pos[0]
                self.dragging_y = True
                self.starty = event.pos[1]
        elif event.type == pygame.MOUSEBUTTONUP:
            if self.x + self.w > event.pos[0] > self.x and self.y + self.h > event.pos[1] > self.y:
                self.dragging_x = False
                self.endx = event.pos[0]
                self.dragging_y = False
                self.endy = event.pos[1]
        elif event.type == pygame.MOUSEMOTION:
            if self.x + self.w > event.pos[0] > self.x and self.y + self.h > event.pos[1] > self.y:
                self.endx = event.pos[0]
                self.endy = event.pos[1]
                
        if self.dragging_x and self.collbar_width_x > 0:
            maxoffset = self.w - self.padding_width * 2 - self.collbar_width_y - self.collbar_width_x
            offset = self.endx - self.startx
            if offset <= 0:
                self.collbar_offset_x = 0
            elif offset >= maxoffset:
                self.collbar_offset_x = maxoffset
            else:
                self.collbar_offset_x = offset
        
        if self.dragging_y and self.collbar_height_y > 0:
            maxoffset = self.h - self.padding_height * 2 - self.collbar_height_x - self.collbar_height_y
            offset = self.endy - self.starty
            if offset <= 0:
                self.collbar_offset_y = 0
            elif offset >= maxoffset:
                self.collbar_offset_y = maxoffset
            else:
                self.collbar_offset_y = offset
        
    def draw(self, win):
        pygame.draw.rect(win, self.color, (self.x, self.y, self.w, self.h))
        if self.border_width > 0:
            pygame.draw.rect(win, self.border_color, (self.x, self.y, self.w, self.h), self.border_width)
        
        #右侧滑动条
        if self.collbar_height_y > 0:
            pygame.draw.rect(win, self.collbar_bgcolor, (self.x+self.w-self.collbar_width_y-self.padding_width, self.y+self.padding_height, self.collbar_width_y, self.h-2*self.padding_height))
            pygame.draw.rect(win, self.collbar_color, (self.x+self.w-self.collbar_width_y-self.padding_width, self.y+self.padding_height+self.collbar_offset_y, self.collbar_width_y, self.collbar_height_y))
        
        #左侧滑动条
        if self.collbar_width_x > 0:
            pygame.draw.rect(win, self.collbar_bgcolor, (self.x+self.padding_width, self.y+self.h-self.padding_height-self.collbar_height_x, self.w-2*self.padding_width-self.collbar_width_y, self.collbar_height_x))
            pygame.draw.rect(win, self.collbar_color, (self.x+self.padding_width+self.collbar_offset_x, self.y+self.h-self.padding_height-self.collbar_height_x, self.collbar_width_x, self.collbar_height_x))
        
        test_texts = self.getTrueLineTexts()
                
        #显示哪些行
        cutPreLineNum = int(self.collbar_offset_y / self.collbar_percent_y // self.char_height)
        test_texts = test_texts[cutPreLineNum:]
        
        #显示哪些列
        showFieldNum = self.getShowFieldNum()
        cutPreFieldNum = int(self.collbar_offset_x / self.collbar_percent_x // self.char_width)
        for i,test_text in enumerate(test_texts):
            test_texts[i] = test_text[cutPreFieldNum:cutPreFieldNum+showFieldNum]
        
        texts = '\n'.join(test_texts).split("\n")
        k = 0
        for i,mytext in enumerate(texts):
            while len(mytext) > self.max_field_num:
                submytext = mytext[0:self.max_field_num]
                
                subtext = self.my_font.render(submytext, True, self.text_color)
                submyx = self.x + self.padding_width
                submyy = self.y + self.padding_height + self.char_height * k
                if submyy+self.char_height < self.y+self.h-self.collbar_height_x:
                    win.blit(subtext, (submyx, submyy))
                
                mytext = mytext[self.max_field_num:]
                k += 1
            
            text = self.my_font.render(mytext, True, self.text_color)
            myx = self.x + self.padding_width
            myy = self.y + self.padding_height + self.char_height * k
            if myy+self.char_height < self.y+self.h-self.collbar_height_x:
                win.blit(text, (myx, myy))
            k += 1
    
    
bt = Button(5, 5, 80, 25)
bt.setText('测试按钮')
bt.setColor('Brown')
bt.setTextColor('Gold')
bt.setBorderColor('Lime')
bt.setBorderWidth(1)

label_text = '''
壹哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈壹
贰哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈贰
叁哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈叁
肆哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈肆
伍哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈伍
陆哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈陆
柒哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈柒
'''.strip()
label = Label(115, 5, 400, 100)
label.setColor('Maroon')
label.setText(label_text)
label.setTextSize(18)
label.setBorderColor('Lime')
label.setBorderWidth(1)

my_text1 = '''
壹哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈壹
贰哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈贰
叁哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈叁
肆哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈肆
伍哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈伍
陆哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈陆
柒哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈柒
'''.strip()
textArea1 = TextArea(535, 5, 400, 145, my_text1, 18)
textArea1.setColor('white')
textArea1.setBorderColor('Lime')
textArea1.setBorderWidth(1)

my_text2 = '''
壹哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈壹
贰哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈贰
叁哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈叁
肆哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈肆
伍哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈伍
陆哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈陆
柒哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈柒
'''.strip()
textArea2 = TextArea(535, 175, 300, 105, my_text2, 14)
textArea2.setColor('white')
textArea2.setBorderColor('Lime')
textArea2.setBorderWidth(1)

running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
            
        textArea1.draggingyMe(event)
        textArea2.draggingyMe(event)
        
        if bt.click(event):
            showMsg("%s被点击了" % bt.getText())
            
    keys_pressed = pygame.key.get_pressed()
    
    #ESC键
    if keys_pressed[pygame.K_ESCAPE]:
        running = False
        
    screen.fill("purple")
    
    bt.draw(screen)
    label.draw(screen)
    
    textArea1.draw(screen)
    textArea2.draw(screen)
        
    #更新显示
    pygame.display.flip()
    #pygame.display.update()
    
    dt = clock.tick(60) / 600
    
pygame.quit()

 

效果:

 

标签:控件,滑块,text,self,height,width,pygame,collbar,哈哈哈
From: https://www.cnblogs.com/xuxiaobo/p/18386646

相关文章

  • QT在控件graphicsView中绘制箭头
    这里写自定义目录标题前言:基础夯实:成功效果展示:失败效果展示:核心代码:前言:对之前箭头没有成功绘制的补充,因为没有直接的箭头项,所以需要自己进行绘制基础夯实:可以直接看,建议看一下之前的绘制过程在控件graphicsView中实现绘图功能(一)在控件graphicsView中实现绘图功......
  • 【C#】【WinForm】 按功能列出常见窗体控件
    Windows窗体提供执行多个功能的控件和组件。下表按常规功能列出了Windows窗体控件和组件。此外,如果存在多个提供相同功能的控件,则会列出推荐的控件,并附有关于它所取代的控件的说明。在单独的后续表中,列出了被取代的控件及其建议的替换项。按功能列出的推荐控件和组件......
  • 界面控件Telerik UI for ASP.NET Core 2024 Q2亮点 - AI与UI的融合
    TelerikUIforASP.NETCore是用于跨平台响应式Web和云开发的最完整的UI工具集,拥有超过60个由KendoUI支持的ASP.NET核心组件。它的响应式和自适应的HTML5网格,提供从过滤、排序数据到分页和分层数据分组等100多项高级功能。本文将介绍界面组件TelerikUIforASP.NETCore在今年......
  • 知名界面控件包DevExpress v24.1.5全新来袭——发布一些重要更改
    DevExpress拥有.NET开发需要的所有平台控件,包含600多个UI控件、报表平台、DevExpressDashboardeXpressApp框架、适用于VisualStudio的CodeRush等一系列辅助工具。屡获大奖的软件开发平台DevExpress近期重要版本v24.1已正式发布,该版本拥有众多新产品和数十个具有高影响力的功......
  • 关于shadow-root影子控件的selenium ui自动化
    首先这个控件和iframe有异曲同工之妙,也是嵌套的一个html,所以定位不能像普通定位一样下面实践一下首先准备一个root.html<!DOCTYPEhtml><html><head><title>带有shadow-root的页面</title></head><body><h1class="test">带有shadow-root的页面</h1>......
  • pygame封装连个常用控件
    #coding=utf-8importos,sys,re,timeimportpygameimportrandomfromwin32apiimportGetSystemMetricsfromtkinterimportmessageboxpygame.init()pygame.display.set_caption("我的控件")percent=0.6screen_width=GetSystemMetrics(0)screen_heig......
  • 【C#】【Winform】自定义控件、自定义事件
    https://blog.csdn.net/m0_62366581/article/details/139553373在开发桌面的过程中,有时候自带的控件样式或者功能上可能不一定能够满足我们的所有要求。这时候,我们需要自定义控件。创建类库项目把图标拖放到资源文件中添加用户控件设置样式尺寸修改代码视图其他项目中复用......
  • pygame手搓贪吃蛇
    代码:#coding=utf-8importos,sys,re,timeimportpygameimportrandomfromwin32apiimportGetSystemMetricsimportcopypygame.init()pygame.display.set_caption("贪吃蛇")percent=0.6screen_width=GetSystemMetrics(0)screen_height=GetSystemM......
  • Vant4+Vue3 实现年月日时分时间范围控件
    <van-popup v-model:show="showDatePick" position="bottom" :overlay-style="{zIndex:1000}"> <van-picker-group title="时间范围" :tabs="['开始日期','结束日期']" @confirm="on......
  • 基于Material Design风格开源的Avalonia UI控件库
    前言今天大姚给大家分享一款基于MaterialDesign风格开源、免费(MITLicense)的AvaloniaUI控件库:Material.Avalonia。当前项目还处于alpha阶段。Avalonia介绍Avalonia是一个强大的框架,使开发人员能够使用.NET创建跨平台应用程序。它使用自己的渲染引擎绘制UI控件,确保在Window......