How to show an interface to select points in python?

989 views Asked by At

Well, I'm programming Conway's game of life in python, and although my program works, the way the user gives the initial points is writing the coordinates of each point.

I want an interface that shows the points with integer coordinates of the cartesian plane, let me select some with the mouse and finally give back the points I selected as tuples(or lists, doesn't matter). Should I download some kind of program or there is a module that has such functionality?

I would also like to ask for some "program" that instead of points, graphs pixels, like in this video. Right now, I'm just using matplotlib to graph, but I think it looks cooler with pixels.

Thanks in advance. EDIT: I didn't want to post the code, for being so long, but here it is.

import matplotlib.pyplot as plt
from string import split

reglas=raw_input("Enter rule of the game(Ej.:B3/23)")
Q=[letra for letra in reglas]
m=Q.index("/")
born, keep=[int(i) for i in Q[1:m]], [int(i) for i in Q[m+1:]]
discard=[x for x in range(1,9) if x not in keep and x not in born]
livecells=set()
a=raw_input("Enter a coordinate (a,b), which will be a living cell. This program will keep you asking coordinates until you decide to stop. To stop, instead of a coordinate, enter stop")
a=tuple([int(float(i)) for i in split(a)])

livecells.add(a)
while True: 
    b=raw_input("Another coordinate")
    if b!="stop":
        b=tuple([int(i) for i in split(b)])
        livecells.add(b)
    else:
        break

def whoisnear(a,b):
    return set([(a+1,b),(a+1,b+1),(a+1,b-1),(a,b+1),(a,b-1),(a-1,b+1),(a-1,b),(a-1,b-1)])
def firstcoordinate(x,y):
    return x
def secondcoordinate(x,y):
    return y
def rectanglearea(c,d,e,f):
    candidates=set()
    for i in range (c-3,d+3):
        for j in range(e-3,f+3):
            candidates.add((i,j))
    return candidates 
Q=[x for (x,y) in livecells]
W=[y for (x,y) in livecells]

plt.plot(Q,W,'ro')
plt.axis([min(Q)-1,max(Q)+1,min(W)-1,max(W)+1])
plt.savefig('0.png')
plt.show()
repetitions=0
minx=min([firstcoordinate(*i) for i in livecells])
maxx=max([firstcoordinate(*i) for i in livecells])
miny=min([secondcoordinate(*i) for i in livecells])
maxy=max([secondcoordinate(*i) for i in livecells])

for j in range(1,30):
    try:
        X={firstcoordinate(*i) for i in livecells}
        Y={secondcoordinate(*i) for i in livecells}
        D=rectanglearea(min(X),max(X),min(Y),max(Y))
        Todiscard=set()
        Toadd=set()
        for i in D:
            K=whoisnear(*i) & livecells
            n=len(K)
            if n in discard:
                Todiscard.add(i)
            elif n in born:
                Toadd.add(i)


        livecells=livecells-Todiscard

        livecells=livecells|Toadd
        firstcords=[x for (x,y) in livecells]
        secondcords=[y for (x,y) in livecells]
        plt.plot(firstcords,secondcords,'ro')
        plt.axis([minx-30,maxx+30,miny-30,maxy+30])
        plt.savefig(str(j)+'.png')
        plt.close()
    except ValueError:
        print j,livecells
        break
1

There are 1 answers

0
TheLazyScripter On

This is a script I developed to extend the pygame module. I don't want to write your code for you but this should get you started! My code is well documented and should be easy for you to understand. Good luck!

Screen Module

import pygame, sys, ctypes, os
from pygame.locals import *
import random

class Screen:
    '''
        --Screen module for handling the pygame display module...
    '''

    def __init__(self, resolution=(640,480), caption=None, transparent=False, icon=None, flags=0):
        '''
            --Grabs and sets the args
            --Grabs the center of the screen based on the monitor resolution
            --Creates a new instance of screen
            '''

        self.resolution = resolution
        self.flags = flags

        if caption:
            self.setCaption(caption)
        if icon:
            self.setIcon(icon)

        self.monitorCenter = self.getCenterScreen(self.getMonitorSize())

        self.centerScreen()

        self.transparent = transparent

        self.screen = self.setScreen()

    def update(self):
        pygame.display.update()


    def setIcon(self, icon):
        '''
            --sets the icon at the icon position on 
                the pygame window. Maintain origonal
                .jpg location

            Usage:
                --self.setIcon(self, 'coolIcon.jpg'
                '''

        try:
            self.icon = icon
            icon = pygame.image.load(icon)
        except:
            self.icon = None
            return
        pygame.display.set_icon(icon)

    def setScreen(self):
        '''
            --creates and returns default pygame window...

            Usage:
                --screen.setScreen()
            '''
        if self.transparent:
            return pygame.display.set_mode(self.resolution, self.flags).convert_alpha()
        return pygame.display.set_mode(self.resolution, self.flags)

    def setCaption(self, caption):
        '''
            --Sets window caption as (caption)...

            Usage:
                --screen.setCaption("My Game!")
            '''

        pygame.display.set_caption(caption)

    def didResize(self):
        info = pygame.display.get_surface()
        return info

    def setMousePos(self, pos):
        '''
            --Sets the mouse at [pos]...

            Usage:
                --screen.setMousePos((250,250))
            '''

        pygame.mouse.set_pos(pos)


    def setScreenPos(self, position):
        '''
            --Sets the windows window argument position to (position)

            Usage:
                --screen.setScreenPos((250,250))
            '''

        os.environ['SDL_VIDEO_WINDOW_POS'] = str(position[0])+','+str(position[1])

    def getMonitorSize(self):
        '''
            --Returns the actual resolution of the active display

            Usage:
                --screen.getMonitorSize()
            '''

        user32 = ctypes.windll.user32
        screenSize = user32.GetSystemMetrics(0), user32.GetSystemMetrics(1)
        return screenSize

    def getCenterScreen(self, res):
        '''
            --Returns the center of the screen based on the monitor 
            --resolution [res] / 2 - window resolution [self.resolution] / 2

            Usage:
                --screen.getCenterScreen((1365,782))
            '''

        center = ((res[0]/2)-self.resolution[0]/2), ((res[1]/2)-self.resolution[1]/2)
        return center

    def centerScreen(self):
        '''
            --sets the center of the pygame window to the 
            --center of the monitor
            --centerScreen() needs to be called before 
            --setScreen() in order for it to center...

            Usage:
                --screen.centerScreen()
            '''

        centerScreen = self.getCenterScreen(self.getMonitorSize())
        self.setScreenPos(centerScreen)

    def getFlags(self):
        '''
            --Returns the flags associated the the active screen...

            Usage:
                --screen.getFlags()
            '''

        return self.getScreenSurface().get_flags()

    def getScreenSurface(self):
        '''
            --Returns the surface object of the active screen...

            Usage:
                --screen.getScreenSurface()
            '''

        return pygame.display.get_surface()

    def getCaption(self):
        '''
            --Returns the current caption associated with the active screen...

            Usage:
                --screen.getCaption()
            '''

        return pygame.display.get_caption()[0]

    def getMousePos(self):
        '''
            --Returns the current mouse position [x,y] on the window...

            Usage:
                --screen.getMousePos()
            '''
        return pygame.mouse.get_pos()

    def closeScreen(self):
        '''
            --De-initializes the screen object...

            Usage:
                --screen.closeScreen()
            '''

        pygame.display.quit()

    def initScreen(self):
        '''
            --Re-initializes the screen object...

            Usage:
                --screen.initScreen()
            '''

        pygame.display.init()

    def resize(self, size):
        '''
            --Creates a new screen instance with resolution of (size)...

                --Overwrites the self.screen object with new size
                --Grabs the New Size, current Caption, and current Flags
                --Closes the current screen instance
                --Creates a new screen instance
                --Places the center of the screen at the center of the monitor
                --Checks if flags contains FULLSCREAN if so it toggles
                --Creates a new display instance with resolution[x,y], and flags(flags)
                --Sets the screen caption

                Usage:
                    --screen.resize((640,480))
            '''

        self.resolution = size
        caption = self.getCaption()
        self.flags = self.getFlags()

        self.closeScreen()
        self.initScreen()

        self.centerScreen()

        if self.flags == FULLSCREEN:
            print self.flags
            self.screen = pygame.display.set_mode((self.resolution),self.flags^FULLSCREEN)
        else:
            self.screen = pygame.display.set_mode((self.resolution),self.flags)
        self.setCaption(caption)

    def toggleFullscreen(self):
        '''
            Module for toggeling between default resolution and fullscreen...

                --Grabs the current screen CAPTION, FLAGS, and MOUSE POSITION
                --Grabs the current surface size
                --Checks to see what resolution the screen is currently at and toggles it
                --Overwrites the self.screen object with new size
                --Closes the current screen instance
                --Creates a new screen instance
                --Places the center of the screen at the center of the monitor
                --Creates a new display instance with resolution[x,y], and flags^FULLSCREEN(toggle)
                --Sets the new screens caption with old caption

                Usage:
                    --screen.toggleFullscreen()
            '''

        caption = self.getCaption()
        self.flags = self.getFlags()

        surface = self.getScreenSurface()
        size = surface.get_width(), surface.get_height()
        if size == self.resolution:
            size = self.getMonitorSize()
        else:
            size = self.resolution

        self.closeScreen()
        self.initScreen()

        self.centerScreen()
        self.screen = pygame.display.set_mode((size),self.flags^FULLSCREEN)
        self.setCaption(caption)
        self.setIcon(self.icon)

class Grid(object):
    def __init__(self, screen, size=(16,16)):
        self.screen = screen
        self.surface = self.screen.screen
        self.size = size
        self.grid = tuple(((x,y) for y in range(0, self.screen.resolution[1], size[1]) for x in range(0, self.screen.resolution[0], size[0])))
        self.elements = self.create_elements()
        self.active_elements = []

    def create_elements(self):
        l = {}
        for x,y in self.grid:
            if x in l:
                l[x].update({y:None})
            else:
                l[x] = {0:None}
        return l
    def set_grid(self, new_size):
        self.grid = ((x,y) for y in range(0, self.screen.resolution[1], new_size[1])for x in range(0, self.screen.resolution[0], new_size[0]))

    def check_active(self):
        self.active_elements = [i for i in [self.elements[x][y] for x,y in self.grid] if i != None]

    def add_element(self, (x,y), color):
        self.elements[x][y] = (color, (x*self.size[0],y*self.size[1], self.size[0], self.size[1]), 0)
        self.check_active()

    def remove_element(self, (x,y)):
        self.elements[x][y] = None
        self.check_active()

    def draw_grid(self):
        for x, y in self.grid:
            pygame.draw.line(self.surface, (255,255,255), (x, 0), (x, self.screen.resolution[0]), 1)
            pygame.draw.line(self.surface, (255,255,255), (0, y), (self.screen.resolution[0], y), 1)

        for elem in self.active_elements:
            pygame.draw.rect(self.surface, *elem)

Main Code

import pygame, sys
from pygame.constants import *
from PyScreen.screen import Screen, Grid
pygame.init()

if __name__ == '__main__':
    my_display = Screen(caption='Conways Game Of Life', resolution=(1280, 720))
    grid = Grid(my_display, (16,16)) #second parameter is the grid size
    grid.add_element((0, 0), (255,255,255)) #anytime you want to add a cell
    grid.add_element((16,16), (255,255,255))
    grid.remove_element((0, 0)) #when you want to remove a cell
    while True:
        for e in pygame.event.get():
            if e.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
        my_display.screen.fill((0,0,0))
        grid.draw_grid()
        my_display.update()