Pygame Basi c калькулятор - PullRequest
       13

Pygame Basi c калькулятор

6 голосов
/ 01 августа 2020

Я пытаюсь сделать калькулятор basi c, но у меня возникла проблема, как вывести текст? Как мне сделать так, чтобы при нажатии кнопки «Плюс» я мог добавить, а если щелкнуть «Разделить», он позволяет мне разделить и отображать результат в желтой части экрана

введите описание изображения здесь

Это то, что у меня есть прямо сейчас. Вы можете запустить его; нет ничего особенного. Мой вопрос в том, как я могу заставить калькулятор сделать так, чтобы, когда я нажимаю плюс, а затем go и складываю числа, он позволяет мне складывать, или когда я нажимаю разделить, он позволяет мне делить мои числа и показывать выходы на экран?

import pygame,math
pygame.init()

window_height = 500
window_width = 500
window  = pygame.display.set_mode((window_height,window_width))

    # the buttons for the shop MENU
class button():
    def __init__(self, color, x,y,width,height, text=''):
        self.color = color
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.text = text
        self.over = False

    def draw(self,window,outline=None):
                #Call this method to draw the button on the screen
        if outline:
            pygame.draw.rect(window, outline, (self.x-2,self.y-2,self.width+4,self.height+4),0)
                    
        pygame.draw.rect(window, self.color, (self.x,self.y,self.width,self.height),0)
                
        if self.text != '':
            font = pygame.font.SysFont('comicsans', 60)
            text = font.render(self.text, 1, (0,0,0))
            window.blit(text, (self.x + (self.width/2 - text.get_width()/2), self.y + (self.height/2 - text.get_height()/2)))

    def isOver(self, pos):
                #Pos is the mouse position or a tuple of (x,y) coordinates
        if pos[0] > self.x and pos[0] < self.x + self.width:
            if pos[1] > self.y and pos[1] < self.y + self.height:
                return True
                    
        return False

    def playSoundIfMouseIsOver(self, pos, sound):
        if self.isOver(pos):            
            if not self.over:
                beepsound.play()
                self.over = True
        else:
            self.over = False
                    
white = (255,255,255)
# the numbers for the calcaltor
s_1s = button((0,255,0),40,450,30,30, '1')
s_2s = button((0,255,0),40,400,30,30, '2')
s_3s = button((0,255,0),40,350,30,30, '3')
s_4s = button((0,255,0),100,450,30,30, '4')
s_5s = button((0,255,0),100,400,30,30, '5')
s_6s = button((0,255,0),100,350,30,30, '6')
s_7s = button((0,255,0),150,450,30,30, '7')
s_8s = button((0,255,0),150,400,30,30, '8')
s_9s = button((0,255,0),150,350,30,30, '9')
s_0s = button((0,255,0),200,450,30,30, '0')

numbers = [s_1s,s_2s,s_3s,s_4s,s_5s,s_6s,s_7s,s_8s,s_9s,s_0s]

# the symbols!
d_1s = button((0,255,0),260,450,30,30, '+')
d_2s = button((0,255,0),260,400,30,30, '-')
d_3s = button((0,255,0),260,350,30,30, 'x')
d_4s = button((0,255,0),200,400,30,30, '÷')

symbols = [d_1s,d_2s,d_3s,d_4s]

# input tap
inputtap = button((253,100,32),10,280,450,50,"")

# redraw window
def redraw():
    # draw all the numbers
    for button in numbers:
        button.draw(window)

    # the symbols
    for button in symbols:
        button.draw(window)

    inputtap.draw(window)
 
def Symbols():
    
    if event.type == pygame.MOUSEBUTTONDOWN:
        pos = pygame.mouse.get_pos()
            
        if d_1s.isOver(pos):
            print("+")

        if d_2s.isOver(pos):
            print("-")

        if d_3s.isOver(pos):
            print("x")

        if d_4s.isOver(pos):
            print("÷")
    

def MOUSEOVERnumbers():
    if event.type == pygame.MOUSEBUTTONDOWN:
        pos = pygame.mouse.get_pos()          
        if s_1s.isOver(pos):
            print("1")
        if s_2s.isOver(pos):
            print("2")
        if s_3s.isOver(pos):
            print("3")
        if s_4s.isOver(pos):
            print("4")
        if s_5s.isOver(pos):
            print("5")
        if s_6s.isOver(pos):
            print("6")
        if s_7s.isOver(pos):
            print("7")
        if s_8s.isOver(pos):
            print("8")
        if s_9s.isOver(pos):
            print("9")
        if s_0s.isOver(pos):
            print("0")            

# the main loop
run = True
while run:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False

        MOUSEOVERnumbers()

        Symbols()

    redraw()
    pygame.display.update()
pygmae.quit()

Ответы [ 2 ]

5 голосов
/ 24 августа 2020

Вы можете добавить кнопку =, чтобы каждый раз, когда пользователь нажимает на нее, вычислять ввод пользователя с помощью функции python eval().

Что касается ввода пользователя, вам сначала нужно его записать глобально. Затем вы можете передать пользовательский ввод в строковое поле inputtap = button((253,100,32),10,280,450,50,""), чтобы отобразить его в окне.

import pygame, math

pygame.init()

window_height = 500
window_width = 600
window  = pygame.display.set_mode((window_height,window_width))

# the buttons for the shop MENU
class button():
    def __init__(self, color, x,y,width,height, text=''):
        self.color = color
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.text = text
        self.over = False

    def draw(self,window,outline=None):
        #Call this method to draw the button on the screen
        if outline:
            pygame.draw.rect(window, outline, (self.x-2,self.y-2,self.width+4,self.height+4),0)
                    
        pygame.draw.rect(window, self.color, (self.x,self.y,self.width,self.height),0)
                
        if self.text != '':
            font = pygame.font.SysFont('comicsans', 60)
            text = font.render(self.text, 1, (0,0,0))
            window.blit(text, (self.x + (self.width/2 - text.get_width()/2), self.y + (self.height/2 - text.get_height()/2)))

    def isOver(self, pos):
        #Pos is the mouse position or a tuple of (x,y) coordinates
        if pos[0] > self.x and pos[0] < self.x + self.width:
            if pos[1] > self.y and pos[1] < self.y + self.height:
                return True
        return False

    def playSoundIfMouseIsOver(self, pos, sound):
        if self.isOver(pos):            
            if not self.over:
                beepsound.play()
                self.over = True
        else:
            self.over = False
                    
white = (255,255,255)
# the numbers for the calcaltor
s_1s = button((0,255,0),40,450,30,30, '1')
s_2s = button((0,255,0),40,400,30,30, '2')
s_3s = button((0,255,0),40,350,30,30, '3')
s_4s = button((0,255,0),100,450,30,30, '4')
s_5s = button((0,255,0),100,400,30,30, '5')
s_6s = button((0,255,0),100,350,30,30, '6')
s_7s = button((0,255,0),150,450,30,30, '7')
s_8s = button((0,255,0),150,400,30,30, '8')
s_9s = button((0,255,0),150,350,30,30, '9')
s_0s = button((0,255,0),200,450,30,30, '0')

numbers = [s_1s,s_2s,s_3s,s_4s,s_5s,s_6s,s_7s,s_8s,s_9s,s_0s]

# the symbols!
d_1s = button((0,255,0),260,450,30,30, '+')
d_2s = button((0,255,0),260,400,30,30, '-')
d_3s = button((0,255,0),260,350,30,30, 'x')
d_4s = button((0,255,0),200,400,30,30, '÷')
d_5s = button((0,255,0),200,350,30,30, '=')
d_6s = button((0,255,0),260,500,30,30, 'C')

symbols = [d_1s,d_2s,d_3s,d_4s,d_5s,d_6s]


# redraw window
def redraw(inputtap):
    # draw all the numbers
    for button in numbers:
        button.draw(window)

    # the symbols
    for button in symbols:
        button.draw(window)

    inputtap.draw(window)

def Symbols():
    global user_input
    global python_input
    global is_finished

    if event.type == pygame.MOUSEBUTTONDOWN:
        pos = pygame.mouse.get_pos()

        try:
            if is_finished or user_input[-1] in ["+", "-", "x", "÷", "="]:
                # User shouldn't type two symbols continuously
                # User shouldn't input any symbols when game finished because there is no number
                return
        except IndexError:
            # User shouldn't input any symbols if there is no number
            return


        if d_1s.isOver(pos):
            print("+")
            user_input += "+"
            python_input += "+"

        if d_2s.isOver(pos):
            print("-")
            user_input += "-"
            python_input += "-"

        if d_3s.isOver(pos):
            print("x")
            user_input += "x"
            python_input += "*"

        if d_4s.isOver(pos):
            print("÷")
            user_input += "÷"
            python_input += "/"

        if d_5s.isOver(pos):
            print("=")
            result = eval(python_input)
            python_input = ""
            user_input += f"={result:.2f}"
            is_finished = True

        if d_6s.isOver(pos):
            print("C")
            python_input = ""
            user_input = ""

def MOUSEOVERnumbers():
    global user_input
    global python_input
    global is_finished

    if event.type == pygame.MOUSEBUTTONDOWN:
        if is_finished:
            user_input = ""
            python_input = ""
            is_finished = False
        pos = pygame.mouse.get_pos()          
        if s_1s.isOver(pos):
            print("1")
            user_input += "1"
            python_input += "1"
        if s_2s.isOver(pos):
            print("2")
            user_input += "2"
            python_input += "2"
        if s_3s.isOver(pos):
            print("3")
            user_input += "3"
            python_input += "3"
        if s_4s.isOver(pos):
            print("4")
            user_input += "4"
            python_input += "4"
        if s_5s.isOver(pos):
            print("5")
            user_input += "5"
            python_input += "5"
        if s_6s.isOver(pos):
            print("6")
            user_input += "6"
            python_input += "6"
        if s_7s.isOver(pos):
            print("7")
            user_input += "7"
            python_input += "7"
        if s_8s.isOver(pos):
            print("8")
            user_input += "8"
            python_input += "8"
        if s_9s.isOver(pos):
            print("9")
            user_input += "9"
            python_input += "9"
        if s_0s.isOver(pos):
            print("0")
            user_input += "0"
            python_input += "0"

# the main loop
run = True
user_input = ""
python_input = ""
is_finished = True

while run:
    # input tap
    inputtap = button((253,100,32),10,280,450,50,f"{user_input}")

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False

        MOUSEOVERnumbers()

        Symbols()

    redraw(inputtap)
    pygame.display.update()

pygame.quit()

Затем вы можете добавить кнопку reset для сброса пользовательского ввода. Также после того, как пользователь нажмет кнопку =, начните новый пользовательский ввод, а не объединяйте старый.

В этом примере кнопка reset помечена как C. Каждый раз, когда пользователь нажимает на нее, очищайте строку ввода пользователя и строку ввода python.

Я также использую глобальную логическую переменную is_finished, чтобы проверить, нажимает ли пользователь кнопку =. Если пользователь нажимает на нее, это означает, что пользователь завершил расчет, так что в следующий раз, когда пользователь нажмет любую кнопку с символами, строка ввода пользователя будет очищена.

Между тем, пользователь не должен вводить два системных символа, кроме C кнопку одновременно. Я сужу об этом, сравнивая вводимые пользователем последние символы и вводимые пользователем текущие символы.

Кроме того, пользователь не должен вводить какой-либо символ перед вводом любого числа. Я сужу по глобальной переменной is_finished. Если is_finished истинно, это означает, что пользователь не начинает ввод, поэтому в строке ввода пользователя нет значения. Я также использую исключение IndexError на всякий случай, потому что пустая строка ввода пользователя не может работать с отрицательным индексом.

Чтобы различать guish между целочисленным результатом и результатом с плавающей запятой, вы можете судить, есть ли точка в результате:

>>> '.' in '45.3'
True
>>> '.' in '453'
False

Наконец, вы также можете упростить эти if logi c с помощью button.text свойств, например, что делает Rabbid76 :

        for number_button in numbers:
            if number_button.isOver(pos):
                print(number_button.text)
                user_input += number_button.text
                python_input += number_button.text
4 голосов
/ 24 августа 2020

Реализуйте класс, который может выполнять арифметические c операции и сохранять текущий текст, который должен отображаться (self.currentText) на дисплее:

class Calculate:
    def __init__(self):
        self.currentValue = 0
        self.newNumber = 0
        self.currentOperation = None
        self.currentText = ""
    def newDigit(self, text):
        self.newNumber = self.newNumber * 10 + int(text) 
        self.currentText = str(self.newNumber)
    def newOperation(self, op):
        try:
            if self.currentOperation == '+':
                self.currentValue += self.newNumber
            elif self.currentOperation == '-':
                self.currentValue -= self.newNumber
            elif self.currentOperation == 'x':
                self.currentValue *= self.newNumber
            elif self.currentOperation == '÷':
                self.currentValue /= self.newNumber
            elif self.currentOperation != "=":
                self.currentValue = self.newNumber
        except:
            self.currentValue = 0
        self.currentOperation = op
        self.currentText = str(self.currentValue)
        self.newNumber = 0

calculator = Calculate()

Нарисовать текст self.currentText в redraw

def redraw():
    # [...]

    inputtap.draw(window)
    inputtext = font.render(calculator.currentText, True, (0, 0, 0))
    window.blit(inputtext, (inputtap.x + inputtap.width - inputtext.get_width() - 4, inputtap.y + 4))

Вызов calculator.newDigit при нажатии di git:

def MOUSEOVERnumbers():
    if event.type == pygame.MOUSEBUTTONDOWN:
        for button in numbers:
            if button.isOver(event.pos):
                print(button.text)  
                calculator.newDigit(button.text)

Вызов calculator.newOperation при нажатии кнопки операции:

def Symbols():  
    if event.type == pygame.MOUSEBUTTONDOWN:
        for button in symbols:
            if button.isOver(event.pos):
                print(button.text)
                calculator.newOperation(button.text)
        if clearButton.isOver(event.pos):
            calculator = Calculate()

См. Полный пример:

import pygame,math
pygame.init()

window_height = 500
window_width = 500
window  = pygame.display.set_mode((window_height,window_width))

font = pygame.font.SysFont('comicsans', 60)

    # the buttons for the shop MENU
class Button():
    def __init__(self, color, x,y,width,height, text=''):
        self.color = color
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.text = text
        self.over = False
        self.image = font.render(self.text, 1, (0,0,0))

    def draw(self,window,outline=None):
                #Call this method to draw the button on the screen
        if outline:
            pygame.draw.rect(window, outline, (self.x-2,self.y-4,self.width+4,self.height+8),0)
                    
        pygame.draw.rect(window, self.color, (self.x,self.y-2,self.width,self.height+4),0)
                
        if self.text != '':
            w, h = self.image.get_size()
            window.blit(self.image, (self.x + (self.width//2 - w//2), self.y + (self.height//2 - h//2 + 2)))

    def isOver(self, pos):
                #Pos is the mouse position or a tuple of (x,y) coordinates
        if pos[0] > self.x and pos[0] < self.x + self.width:
            if pos[1] > self.y and pos[1] < self.y + self.height:
                return True
                    
        return False

    def playSoundIfMouseIsOver(self, pos, sound):
        if self.isOver(pos):            
            if not self.over:
                beepsound.play()
                self.over = True
        else:
            self.over = False

class Calculate:
    def __init__(self):
        self.currentValue = 0
        self.newNumber = 0
        self.currentOperation = None
        self.currentText = ""
    def newDigit(self, text):
        self.newNumber = self.newNumber * 10 + int(text) 
        self.currentText = str(self.newNumber)
    def newOperation(self, op):
        try:
            if self.currentOperation == '+':
                self.currentValue += self.newNumber
            elif self.currentOperation == '-':
                self.currentValue -= self.newNumber
            elif self.currentOperation == 'x':
                self.currentValue *= self.newNumber
            elif self.currentOperation == '÷':
                self.currentValue /= self.newNumber
            elif self.currentOperation != "=":
                self.currentValue = self.newNumber
        except:
            self.currentValue = 0
        self.currentOperation = op
        self.currentText = str(self.currentValue)
        self.newNumber = 0

calculator = Calculate()
        
                    
white = (255,255,255)
# the numbers for the calcaltor
s_1s = Button((0,255,0),40,450,30,30, '1')
s_2s = Button((0,255,0),40,400,30,30, '2')
s_3s = Button((0,255,0),40,350,30,30, '3')
s_4s = Button((0,255,0),100,450,30,30, '4')
s_5s = Button((0,255,0),100,400,30,30, '5')
s_6s = Button((0,255,0),100,350,30,30, '6')
s_7s = Button((0,255,0),150,450,30,30, '7')
s_8s = Button((0,255,0),150,400,30,30, '8')
s_9s = Button((0,255,0),150,350,30,30, '9')
s_0s = Button((0,255,0),200,450,30,30, '0')

numbers = [s_1s,s_2s,s_3s,s_4s,s_5s,s_6s,s_7s,s_8s,s_9s,s_0s]

# the symbols!
d_1s = Button((0,255,0),260,450,30,30, '+')
d_2s = Button((0,255,0),260,400,30,30, '-')
d_3s = Button((0,255,0),260,350,30,30, 'x')
d_4s = Button((0,255,0),200,400,30,30, '÷')
d_5s = Button((0,255,0),320,450,30,30, '=')

symbols = [d_1s,d_2s,d_3s,d_4s,d_5s]

clearButton = Button((0,255,0),200,350,30,30, 'C')

allButtons = numbers + symbols + [clearButton]

# input tap
inputtap = Button((253,100,32),10,280,450,50,"")

# redraw window
def redraw():
    for button in allButtons:
        button.draw(window)

    inputtap.draw(window)
    inputtext = font.render(calculator.currentText, True, (0, 0, 0))
    window.blit(inputtext, (inputtap.x + inputtap.width - inputtext.get_width() - 4, inputtap.y + 4))
 
def Symbols():  
    global calculator
    if event.type == pygame.MOUSEBUTTONDOWN:
        for button in symbols:
            if button.isOver(event.pos):
                print(button.text)
                calculator.newOperation(button.text)
        if clearButton.isOver(event.pos):
            calculator = Calculate()
    
def MOUSEOVERnumbers():
    if event.type == pygame.MOUSEBUTTONDOWN:
        for button in numbers:
            if button.isOver(event.pos):
                print(button.text)  
                calculator.newDigit(button.text)

# the main loop
run = True
while run:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False

        MOUSEOVERnumbers()
        Symbols()

    redraw()
    pygame.display.update()
pygmae.quit()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...