|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
代码太长,我没写注释,问chatgpt他说我代码太长不肯回我
- import pygame
- from selenium import webdriver
- from requests import get
- from subprocess import getstatusoutput as _gsout
- from threading import Thread, Timer
- from os import remove
- from os.path import isfile
- from pickle import load, dump
- from time import sleep
- from bs4 import BeautifulSoup
- from lxml import html
- pygame.init()
- pygame.key.set_repeat(1000, 50)
- class Button(pygame.sprite.Sprite):
- def __init__(self, name, size, font: pygame.font.Font, bgc, fgc, pos, key='\0'):
- pygame.sprite.Sprite.__init__(self)
- self.image = pygame.Surface(size)
- self.image.fill(bgc)
- surf = font.render(name, False, fgc)
- rect = surf.get_rect()
- rect.center = self.image.get_rect().center
- self.image.blit(surf, rect)
- self.rect = self.image.get_rect()
- self.rect.topleft = pos
- self.key = key
- self.font = font
- self.bgc = bgc
- self.fgc = fgc
-
- def chosen(self, event: pygame.event.Event):
- if event.type == pygame.MOUSEBUTTONUP:
- if self.rect.collidepoint(event.pos):
- return True
- if event.type == pygame.KEYDOWN:
- if event.key == ord(self.key) and event.mod & pygame.KMOD_ALT:
- return True
- return False
- def draw(self):
- screen.blit(self.image, self.rect)
- class Text(pygame.sprite.Sprite):
- def __init__(self, text, font, color, pos):
- pygame.sprite.Sprite.__init__(self)
- self.font = font
- self._text = text
- self.color = color
- self.image = self.font.render(self.text, False, self.color)
- self.rect = self.image.get_rect()
- self.rect.topleft = pos
-
- def draw(self):
- screen.blit(self.image, self.rect)
- @property
- def text(self):
- return self._text
- @text.setter
- def text(self, new):
- self._text = new
- self.image = self.font.render(self.text, False, self.color)
- class Entry(pygame.sprite.Sprite):
- def __init__(self, size, font, bgc, bdc, fgc, pos):
- pygame.sprite.Sprite.__init__(self)
- self.bgc = bgc
- self.bdc = bdc
- self.image = pygame.Surface(size)
- self.image.fill(bgc)
- for x in range(0, size[0]):
- self.image.set_at((x, 0), bdc)
- self.image.set_at((x, size[1] - 1), bdc)
- for y in range(0, size[1]):
- self.image.set_at((0, y), bdc)
- self.image.set_at((size[0] - 1, y), bdc)
- self.text = Text('', font, fgc, pos)
- self.image.blit(self.text.image, (0, 0))
- self.rect = self.image.get_rect()
- self.rect.topleft = pos
- self.selected = False
-
- @property
- def fgc(self):
- return self.text.color
- def draw(self):
- screen.blit(self.image, self.rect)
-
- def listen(self, event):
- if event.type == pygame.MOUSEBUTTONDOWN:
- self.selected = self.rect.collidepoint(event.pos)
- elif event.type == pygame.KEYDOWN:
- if self.selected:
- if event.key == pygame.K_BACKSPACE:
- self.text.text = self.text.text[:-1]
- self._update_text()
- elif (event.unicode in
- 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()_+[];,./{}|:"<>?'
- + "'" + '\\'
- ):
- self.text.text += event.unicode
- self._update_text()
-
- def _update_text(self):
- size = self.rect.size
- self.image = pygame.Surface(size)
- self.image.fill(self.bgc)
- for x in range(0, size[0]):
- self.image.set_at((x, 0), self.bdc)
- self.image.set_at((x, size[1] - 1), self.bdc)
- for y in range(0, size[1]):
- self.image.set_at((0, y), self.bdc)
- self.image.set_at((size[0] - 1, y), self.bdc)
- self.text = Text(self.text.text, self.text.font, self.fgc, self.rect.topleft)
- self.image.blit(self.text.image, (0, 0))
- class PasswordEntry(Entry):
- def _update_text(self):
- size = self.rect.size
- self.image = pygame.Surface(size)
- self.image.fill(self.bgc)
- for x in range(0, size[0]):
- self.image.set_at((x, 0), self.bdc)
- self.image.set_at((x, size[1] - 1), self.bdc)
- for y in range(0, size[1]):
- self.image.set_at((0, y), self.bdc)
- self.image.set_at((size[0] - 1, y), self.bdc)
- self.text = Text(len(self.text.text) * '*', self.text.font, self.fgc, self.rect.topleft)
- self.image.blit(self.text.image, (0, 0))
- class MyThread(Thread):
- def __init__(self, func, args=(), kwargs=None, timeout=None):
- Thread.__init__(self)
- self.func = func
- self.args = args
- self.kwargs = {} if kwargs is None else kwargs
- self.timeout = timeout
- self.result = None
-
- def run(self):
- self.result = self.func(*self.args, **self.kwargs)
- def timeout(seconds):
- def decorated(func):
- def done(*args, **kwargs):
- err = None
- result = None
- def inner():
- nonlocal err, result
- try:
- result = func(*args, **kwargs)
- except BaseException as msg:
- err = msg
- thread = Thread(target=inner)
- thread.start()
- # 只等待seconds秒
- thread.join(seconds)
- # 如果线程还活着
- if thread.is_alive():
- raise TimeoutError
- if err:
- raise err
- return result
- return done
- return decorated
- # 实际上是生成了一个新的decorated函数,通过闭包的形式保存了秒数,然后done里再调用inner
- @timeout(1)
- def soutf(msg):
- return _gsout(msg)
- def check_internet():
- try:
- soutf('ping fishc.com.cn')
- # 这东西,报错可是最快
- print('你没联网')
- exit()
- except TimeoutError:
- # 连上了的话那就好说
- pass
- def load_image(url):
- filename = 'temp.png'
- with open(filename, 'wb') as f:
- f.write(get(url, headers={
- 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36'
- }).content)
- image = pygame.image.load(filename)
- remove(filename)
- return image
- def save():
- with open('fishc.set', 'wb') as f:
- dump(data, f)
- def loginf(email, password):
- driver.get('https://fishc.com.cn/member.php?mod=logging&action=login')
- sleep(1)
- driver.find_element(
- 'xpath',
- '/html/body/div[6]/div/div[2]/div/div[2]/div[1]/div[1]/form/div/div[1]/table/tbody/tr/td[1]/input'
- ).send_keys(email)
- driver.find_element(
- 'xpath',
- '/html/body/div[6]/div/div[2]/div/div[2]/div[1]/div[1]/form/div/div[2]/table/tbody/tr/td[1]/input'
- ).send_keys(password)
- driver.find_element(
- 'xpath',
- '/html/body/div[6]/div/div[2]/div/div[2]/div[1]/div[1]/form/div/div[6]/table/tbody/tr/td[1]/button'
- ).click()
- sleep(1)
- driver.find_element('id', 'succeedmessage_href').click()
- return driver.page_source
- def getdata(source):
- tree = html.fromstring(source)
- part = html.tostring(tree.xpath('//strong[@class="vwmy"]')[0], encoding='unicode')
- usergroup = html.tostring(tree.xpath('//a[@id="g_upmine"]')[0], encoding='unicode')
- soup = BeautifulSoup(part, features='lxml')
- soup2 = BeautifulSoup(usergroup, features='lxml')
- return soup.find('a').text, soup2.find('font').get('color'), soup2.find('font').text
- def login_to1(email, password):
- return getdata(loginf(email, password))
- def login_to(email, password):
- result = login_to1(email, password)
- Timer(3, hide_msg).start()
- return result
- def hide_msg():
- global state
- state = 3
- check_internet()
- size = width, height = (640, 480)
- screen = pygame.display.set_mode(size)
- logo = load_image('https://fishc.com.cn/static/image/common/logo.png')
- icon = load_image('https://fishc.com.cn/favicon.ico')
- pygame.display.set_caption('FishC App')
- pygame.display.set_icon(icon)
- font15 = pygame.font.SysFont('microsoftyaheiui', 15)
- font20 = pygame.font.SysFont('microsoftyaheiui', 20)
- font20b = pygame.font.SysFont('microsoftyaheiui', 20)
- font20b.set_bold(True)
- chrome = Button('[C]hrome', (100, 50), font20, (0, 255, 0), (0, 0, 0), (100, 200), 'c')
- firefox = Button('[F]irefox', (100, 50), font20, (0, 255, 0), (0, 0, 0), (300, 200), 'f')
- c_chrome = Button('Change driver(Using Chrome)', (200, 50), font15, (255, 255, 255), (0, 0, 0), (width - 200, 0))
- c_firefox = Button('Change driver(Using Firefox)', (200, 50), font15, (255, 255, 255), (0, 0, 0), (width - 200, 0))
- change = c_chrome
- login = Button('登录(L)', (100, 50), font20, (0, 0, 255), (255, 255, 255), (width - 123, height - 100), 'l')
- save1 = Button('保存数据(S)', (150, 50), font20, (0, 0, 255), (255, 255, 255), (width // 2 - 125, height // 2 - 50), 's')
- unsave = Button('不保存数据(N)', (150, 50), font20, (0, 0, 255), (255, 255, 255), (width // 2 - 125, height // 2 + 50), 'n')
- swin = pygame.Rect(width // 4, height // 4, width // 2, height // 2)
- username = Entry((200, 30), font20, (255, 255, 255), (0, 0, 127), (0, 0, 0), (200, 100))
- pwd = Entry((200, 30), font20, (255, 255, 255), (0, 0, 127), (0, 0, 0), (200, 180))
- t_user = Text('用户名/邮箱', font20b, (0, 0, 0), (90, 100))
- t_pwd = Text('密码', font20b, (0, 0, 0), (100, 180))
- logining = Text('', font15, (0, 0, 0), (300, 200))
- succed = Text('', font15, (0, 0, 0), (width - 150, 10))
- data = {
- 'driver': None,
- 'username': None,
- 'password': None
- }
- state = 0
- if isfile('fishc.set'):
- with open('fishc.set', 'rb') as f:
- data = load(f)
- thread = None
- clock = pygame.time.Clock()
- running = True
- while running:
- clock.tick(30)
- screen.fill((255, 255, 255))
- screen.blit(logo, (0, 0))
- if state == 1:
- pygame.draw.rect(screen, (0, 0, 0), swin, 2)
- save1.draw()
- unsave.draw()
- elif state == 0:
- if data['driver'] is None:
- chrome.draw()
- firefox.draw()
- else:
- change.draw()
- if data['username'] is None or data['password'] is None:
- username.draw()
- t_user.draw()
- pwd.draw()
- t_pwd.draw()
- login.draw()
- elif state == 2:
- if thread.result is None:
- logining.text = '登录中...'
- else:
- logining.text = '登录成功!'
- logining.draw()
- elif state == 3:
- succed.text = f'{thread.result[0]}(用户组: {thread.result[2]})'
- succed.color = thread.result[1]
- succed.rect.topleft = (width - succed.rect.width - 10, 10)
- succed.draw()
- for event in pygame.event.get():
- if event.type == pygame.QUIT:
- if state == 1:
- running = False
- # 虽然只会退出for
- break
- state = 1
- if state == 1:
- if save1.chosen(event):
- save()
- running = False
- elif unsave.chosen(event):
- running = False
- else:
- if data['driver'] is None:
- temp = False
- if chrome.chosen(event):
- data['driver'] = (webdriver.Chrome, webdriver.ChromeOptions)
- change = c_chrome
- temp = True
- elif firefox.chosen(event):
- data['driver'] = (webdriver.Firefox, webdriver.FirefoxOptions)
- change = c_firefox
- temp = True
- if temp:
- option = data['driver'][1]()
- option.add_argument('headless')
- driver = data['driver'][0](options=option)
- else:
- if data['username'] is None or data['password'] is None:
- username.listen(event)
- pwd.listen(event)
- if change.chosen(event):
- data['driver'] = None
- if login.chosen(event):
- data['username'] = username.text.text
- data['password'] = pwd.text.text
- state = 2
- thread = MyThread(func=login_to, args=(username.text.text, pwd.text.text))
- thread.start()
- pygame.display.flip()
- pygame.quit()
- driver.close()
复制代码
就这么一个文件
main1.zip
(3.61 KB, 下载次数: 1)
picture:
抱歉,看起来是文本的渲染方式导致的。为了使文本更精确地居中,可以在绘制文本前计算文本宽度的一半,并将其减去屏幕宽度的一半。这样可以确保文本在屏幕中心位置上。修改代码如下:
1. 在 Text 类中添加一个方法 draw_centered ,用于计算并绘制居中的文本:
- class Text:
- # 省略其他代码...
- def draw_centered(self, surface):
- self.surface = self.font.render(self.text, True, self.color)
- self.rect = self.surface.get_rect()
- self.rect.center = (width // 2, height // 2)
- surface.blit(self.surface, self.rect.topleft)
复制代码
2. 更新 state == 3 的情况,使用新的 draw_centered 方法绘制居中的文本:
- elif state == 3:
- succed.text = f'{thread.result[0]}(用户组: {thread.result[2]})'
- succed.color = thread.result[1]
- succed.draw_centered(screen)
复制代码
这样,当登录成功后,用户名和用户组信息将准确显示在屏幕正中间。
|
|