pygame - 向下滚动页面

时间:2014-07-01 20:15:50

标签: python scroll pygame

简而言之,我的程序是一个联系人应用程序,这显然意味着一个人需要能够在应用程序中存储多个联系人,这反过来意味着联系人最终会去"关闭&# 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传递输入。

1 个答案:

答案 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)

enter image description here

相关问题