简而言之,我的程序是一个联系人应用程序,这显然意味着一个人需要能够在应用程序中存储多个联系人,这反过来意味着联系人最终会去"关闭&# 34;屏幕,所以我需要能够向下滚动页面,以便一个人可以看到他们所有的联系人并与特定联系人互动。
然而,我有点腌渍......我该怎么做?我遇到的问题是应用程序是一个固定的宽度和高度,所以我不能向下滚动页面只是为了发现背景是黑色的,因为我的矩形只是长度很长作为应用程序窗口长度。另一个问题是我不知道如何推动'屏幕了。我不知道。
到目前为止,这是该程序的代码:
import pickle
import operator
import pygame
import sys
from pygame.locals import *
from itertools import groupby
#create Contact class
class Contact():
def __init__(self, firstName, lastName, address, groupType,
telephone, mobile, email, photoField):
self.firstName = firstName
self.lastName = lastName
self.address = address
self.groupType = groupType
self.telephone = telephone
self.mobile = mobile
self.email = email
self.photoField = photoField
def showDetails(self):
print("First Name:\t", self.firstName)
print("Last Name:\t", self.lastName)
print("Address:\t", self.address)
print("Telephone:\t", self.telephone)
print("Mobile:\t", self.mobile)
print("Email:\t", self.email)
@classmethod
def from_input(cls):
firstName = input("First Name: ")
lastName = input("Last Name: ")
address = input("Address: ")
telephone = input("Telephone: ")
mobile = input("Mobile: ")
email = input("Email: ")
return cls(firstName, lastName, address, None,
telephone, mobile, email, None)
class AddressBook():
def __init__(self):
self.contactsList = pickle.load(open("save.p", "rb"))
def addContact(self, contact = None):
if contact is None:
contact = Contact.from_input()
self.contactsList.append(contact)
pickle.dump(self.contactsList, open("save.p", "wb"))
def delContact(self, contact = None):
if contact is None:
search = input("Search: ")
for i in self.contactsList:
if (i.firstName.lower() == search.lower()) or (i.lastName.lower() == search.lower()):
indexed = self.contactsList.index(i)
del self.contactsList[indexed]
pickle.dump(self.contactsList, open("save.p", "wb"))
elif (i.firstName.lower() != search.lower()) or (i.lastName.lower() != search.lower()):
continue
def contactInfo(self, contact = None):
if contact is None:
search = input("Search: ")
print()
#display contact information
for i in self.contactsList:
if (i.firstName.lower() == search.lower()) or (i.lastName.lower() == search.lower()):
i.showDetails()
print()
elif (i.firstName.lower() != search.lower()) or (i.lastName.lower() != search.lower()):
continue
else:
print("No contacts\n")
def contactSearch(self, contact = None):
if contact is None:
search = input("Search: ")
print()
for i in self.contactsList:
if (i.firstName.lower() == search.lower()) or (i.lastName.lower() == search.lower()):
print(i.firstName, i.lastName)
print()
elif (i.firstName.lower() != search.lower()) or (i.lastName.lower() != search.lower()):
continue
else:
print("No contacts\n")
class Page():
def __init__(self, screen = pygame.display.set_mode((320, 480)), caption = pygame.display.set_caption("Contacts")):
self.screen = screen
self.caption = caption
def style(self):
pygame.draw.rect(self.screen, (171,0,0), (0,0,320,63), 0)
pygame.draw.rect(self.screen, (230,230,230), (0,63,320,417), 0)
pygame.draw.line(self.screen, (120,0,0), (5,61), (320, 61), 2)
class MainPage(Page):
def __init__(self, screen = pygame.display.set_mode((320, 480)), caption = pygame.display.set_caption("Contacts"), title = "Contacts"):
Page.__init__(self, screen, caption)
self.title = title
def style(self):
Page.style(self)
titleFont = pygame.font.SysFont("trebuchet ms", 38)
textSurface = titleFont.render(self.title, True, (255,255,255))
self.screen.blit(textSurface, (5, 18))
AddButton().shape()
def printContacts(self):
addressBook = AddressBook()
addressBook.contactsList
addressBook.contactsList.sort(key = lambda c: (c.lastName, c.firstName) if c.lastName else (c.firstName, ""))
contactFont = pygame.font.SysFont("trebuchet ms", 18)
y = 80
for (key, g) in groupby(addressBook.contactsList, lambda c: c.lastName[0] if c.lastName else c.firstName[0]):
groupName = contactFont.render(key, True, (171,0,0))
self.screen.blit(groupName, (5, y))
pygame.draw.line(self.screen, (0,0,0), (5,(y+20)), (320, (y+20)), 1)
y += 30
for i in g:
name = i.firstName + " " + i.lastName
textName = contactFont.render(name, True, (0,0,0))
pygame.draw.line(self.screen, (210,210,210), (5,(y+20)), (320, (y+20)), 1)
self.screen.blit(textName, (5, y))
y += 30
class AddPage(Page):
def __init__(self, screen = pygame.display.set_mode((320, 480)), caption = pygame.display.set_caption("Contacts"), title = "Add Contact"):
Page.__init__(self, screen, caption)
self.title = title
def style(self):
Page.style(self)
titleFont = pygame.font.SysFont("trebuchet ms", 38)
textSurface = titleFont.render(self.title, True, (255,255,255))
self.screen.blit(textSurface, (5, 18))
AddButton().shape()
CancelButton().shape()
class Button():
def __init__(self, screen = pygame.display.set_mode((320, 480))):
self.screen = screen
def shape(self):
pygame.draw.rect(self.screen, (120,0,0), (270,12,40,40), 0)
class AddButton(Button):
def __init__(self, screen = pygame.display.set_mode((320, 480))):
Button.__init__(self, screen)
def shape(self):
Button.shape(self)
pygame.draw.line(self.screen, (255,255,255), (289, 15), (289,48), 2)
pygame.draw.line(self.screen, (255,255,255), (272, 31.5), (307, 31.5), 2)
class CancelButton(Button):
def __init__(self, screen = pygame.display.set_mode((320, 480))):
Button.__init__(self, screen)
def shape(self):
pygame.draw.rect(self.screen, (120,0,0), (245,20,25,25), 0)
pygame.draw.aaline(self.screen, (255,255,255), (252,32.5), (263,26))
pygame.draw.aaline(self.screen, (255,255,255), (252,32.5), (263,39))
pygame.init()
page = MainPage()
page.style()
page.printContacts()
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
elif event.type == KEYDOWN and event.key == K_ESCAPE:
pygame.quit()
sys.exit()
elif event.type == MOUSEBUTTONUP and event.button == 1 and isinstance(page, MainPage):
if (pygame.mouse.get_pos() >= (270,13)) and (pygame.mouse.get_pos() >= (270,53)) and (pygame.mouse.get_pos() <= (309,13)) and (pygame.mouse.get_pos() <= (309,53)):
page = AddPage()
page.style()
elif event.type == MOUSEBUTTONUP and event.button == 1 and isinstance(page, AddPage):
if (pygame.mouse.get_pos() >= (270,13)) and (pygame.mouse.get_pos() >= (270,53)) and (pygame.mouse.get_pos() <= (309,13)) and (pygame.mouse.get_pos() <= (309,53)):
page = MainPage()
page.style()
page.printContacts()
elif (pygame.mouse.get_pos() >= (245,20)) and (pygame.mouse.get_pos() >= (245,45)) and (pygame.mouse.get_pos() <= (370,20)) and (pygame.mouse.get_pos() <= (370,45)):
page = MainPage()
page.style()
page.printContacts()
pygame.display.update()
addressBook = AddressBook()
addressBook.contactsList
addressBook.contactsList.sort(key = lambda c: (c.lastName, c.firstName) if c.lastName else (c.firstName, ""))
print("-------------------\nContacts\n")
for i in addressBook.contactsList:
print(i.firstName, i.lastName)
print()
print("Menu:\n\n1. Add Contact\n2. Show Contact Details\n3. Edit Contact\n4. Delete Contact\n5. Search Contact\n-------------------\n")
choice = input()
print()
if choice == "1":
#add contacts
contact = AddressBook().addContact()
elif choice == "2":
contact = AddressBook().contactInfo()
elif choice == "4":
contact = AddressBook().delContact()
elif choice == "5":
contact = AddressBook().contactSearch()
else:
continue
我为pygame代码和原始python代码的混合道歉,因为我仍然无法将shell代码完全转换为pygame可用的代码。因此,联系人条目等仍然通过Shell /控制台完成。我首先要完成主屏幕,然后继续实际能够通过pygame传递输入。
答案 0 :(得分:6)
正如furas在评论中已经说过的,最好使用像Tkinter或PyQt等GUI框架,特别是因为如果你坚持使用pygame,文本输入将是你的主要PITA。 pygame有一些小部件库,但与“真正的”GUI框架相比,它们都吮吸了IMHO。
尽管如此,还是有一种简单的方法可以将滚动添加到您的应用程序中。不要将您的内容直接绘制到屏幕上,而是将其blit到高于屏幕Surface
的中间Surface
。如果您想向下滚动,只需在屏幕Surface
上方显示此中间Surface
“。
以下是使用鼠标滚轮滚动的简单示例:
import pygame
import string
pygame.init()
screen = pygame.display.set_mode((300, 300))
intermediate = pygame.surface.Surface((300, 600))
i_a = intermediate.get_rect()
x1 = i_a[0]
x2 = x1 + i_a[2]
a, b = (255, 0, 0), (60, 255, 120)
y1 = i_a[1]
y2 = y1 + i_a[3]
h = y2-y1
rate = (float((b[0]-a[0])/h),
(float(b[1]-a[1])/h),
(float(b[2]-a[2])/h)
)
for line in range(y1,y2):
color = (min(max(a[0]+(rate[0]*line),0),255),
min(max(a[1]+(rate[1]*line),0),255),
min(max(a[2]+(rate[2]*line),0),255)
)
pygame.draw.line(intermediate, color, (x1, line),(x2, line))
y = 20
f = pygame.font.SysFont('', 17)
for l in string.ascii_uppercase:
intermediate.blit(f.render(l, True, (255, 255, 255)), (10, y))
y += 20
clock = pygame.time.Clock()
quit = False
scroll_y = 0
while not quit:
quit = pygame.event.get(pygame.QUIT)
for e in pygame.event.get():
if e.type == pygame.MOUSEBUTTONDOWN:
if e.button == 4: scroll_y = min(scroll_y + 15, 0)
if e.button == 5: scroll_y = max(scroll_y - 15, -300)
screen.blit(intermediate, (0, scroll_y))
pygame.display.flip()
clock.tick(60)