2

I finally finished a dice roll program I've been working on and I want to add one last thing: I want to add a button that says "Roll Dice". Is there a way to run a Python script with a Tkinter button? I've tried to use:

from tkinter import *

master = Tk()

def callback():
CODE HERE

b = Button(master, text="BUTTON TEXT", command=callback)
b.pack()

mainloop()

but when I use that, the pygame window is just black.

The code for my program is:

exec(open("Dice Crop.py").read(), globals())
from pygame.locals import *
from random import randint
from tkinter import *
import pygame
import sys

pygame.init()

font = pygame.font.SysFont("comicsansms",30)

screen = pygame.display.set_mode((284,177),0,32)

background = pygame.image.load("background.jpg").convert()

one = pygame.image.load("one.png").convert_alpha()
two = pygame.image.load("two.png").convert_alpha()
three = pygame.image.load("three.png").convert_alpha()
four = pygame.image.load("four.png").convert_alpha()
five = pygame.image.load("five.png").convert_alpha()
six = pygame.image.load("six.png").convert_alpha()

counter = 0

while True:
    for evt in pygame.event.get():
        if evt.type == pygame.QUIT:
            pygame.quit()
            sys.exit()

    screen.blit(background,(0, 0))

    if counter < 20:
        n = randint(1,6)
        counter += 1

    if n == 1:
        screen.blit(one,(100,50))
        screen.blit(font.render("1",True,(0,200,0)),(125,130))
    if n == 2:
        screen.blit(two,(100,50))
        screen.blit(font.render("2",True,(0,200,0)),(125,130))
    if n == 3:
        screen.blit(three,(100,50))
        screen.blit(font.render("3",True,(0,200,0)),(125,130))
    if n == 4:
        screen.blit(four,(100,50))
        screen.blit(font.render("4",True,(0,200,0)),(125,130))
    if n == 5:
        screen.blit(five,(100,50))
        screen.blit(font.render("5",True,(0,200,0)),(125,130))
    if n == 6:
        screen.blit(six,(100,50))
        screen.blit(font.render("6",True,(0,200,0)),(125,130))
    if counter < 20:
        print(n)
    if counter == 20:
        print(">",n,"<")


    pygame.time.delay(100)
    pygame.display.update()

(All exec(open("Dice Crop.py").read(), globals()) does is open a Python script that takes one image with multiple dice and slices it into separate images.)

Nisse Engström
  • 4,738
  • 23
  • 27
  • 42
retardiot
  • 33
  • 5
  • You can easily create a very simple button in pygame with the help of a `pygame.Rect` and its collision detection methods. You don't need tkinter. It's also very odd that you have to exec another Python script. Slicing an image is something you can do with pygame as well, and if you want to do it in another file, then you should import the sliced images and not exec the file. – skrx Aug 20 '17 at 15:57
  • I've posted a solution with a `pygame.Rect`, but I'll check out if this can be achieved with tkinter, too. However, I don't know how well pygame and tkinter work together. – skrx Aug 20 '17 at 16:16
  • [Here's an answer](https://stackoverflow.com/a/16550818/6220679) that shows you how to embed a pygame display into a tkinter.Frame, but it kind of looks strange and I'd rather use one of the GUI libraries for pygame (like [SGC](http://pygame.org/project-SGC-2089-4505.html)) or just a rect. – skrx Aug 21 '17 at 12:35

1 Answers1

0

You can just use a pygame.Rect as a button. Rects have a collidepoint method to which you can pass the mouse position when the user clicks a mouse button. Mouse events have a pos attribute which you can pass to collidepoint, or alternatively call pygame.mouse.get_pos().

from random import randint
import pygame
import sys

pygame.init()

font = pygame.font.SysFont("comicsansms", 30)
screen = pygame.display.set_mode((284, 177), 0, 32)

one = font.render("1", True, (0,200,0))
two = font.render("2", True, (0,200,0))
three = font.render("3", True, (0,200,0))
four = font.render("4", True, (0,200,0))
five = font.render("5", True, (0,200,0))
six = font.render("6", True, (0,200,0))
# Put the images into a list or dictionary to
# avoid the repetition in the while loop.
dice = [one, two, three, four, five, six]

button = pygame.Rect(5, 5, 120, 40)
button_text = font.render("roll dice", True, (0,200,0))
rolling = False
counter = 0
n = 0

while True:
    for evt in pygame.event.get():
        if evt.type == pygame.QUIT:
            pygame.quit()
            sys.exit()
        elif evt.type == pygame.MOUSEBUTTONDOWN:
            # Check if the mouse clicked on the button.
            if button.collidepoint(evt.pos):
                # Start rolling and reset the counter.
                rolling = True
                counter = 0

    if rolling:
        if counter < 20:
            n = randint(1,6)
            counter += 1
            print(n)
        elif counter == 20:
            rolling = False
            print(">",n,"<")

    screen.fill((30, 30, 30))
    pygame.draw.rect(screen, (70, 80, 90), button)
    screen.blit(button_text, (button.x+3, button.y-2))
    # Blit the current image (index [n-1] of the list).
    screen.blit(dice[n-1],(100,50))

    pygame.time.delay(100)
    pygame.display.update()
skrx
  • 19,980
  • 5
  • 34
  • 48