In this code, self.canvas.clear() does erase a previously drawn board upon resize. However, it doesn't eliminate the images, and I found no method or variable in Image() that would help me do that. Instead, the images duplicate and hang in the background.
Here's the minimal example, all collapsed down from three different programs:
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.widget import Widget
from kivy.uix.image import AsyncImage
from kivy.config import Config
from kivy import graphics
def decodeFEN(from_path="FEN_now.txt"):
this_FEN = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1".split(" ")
piece_placement = this_FEN[0]
for x in range(1, 9):
piece_placement = piece_placement.replace(str(x), "1" * x)
piece_placement = [list(a) for a in piece_placement.split("/")]
this_FEN[0] = piece_placement
print(this_FEN)
return this_FEN
def encodeFEN(): #TODO: Create a program that renders a board state to an FEN.
pass
class GameState():
def __init__(self):
self.fen_state = decodeFEN()
self.board = list(sorted([c for d in
[[(a, (7 - b), self.fen_state[0][b][a], chr(a+97)+str(8-b)) for b in range(0,8)] for a in range(0,8)]
for c in d], key=lambda i: (i[1], i[0])))
# Define the pieces as a dictionary of the FEN keys to image values.
def loadImages():
images = {}
for p in ["b", "k", "n", "q", "p", "r",
"B", "K", "N", "Q", "P", "R"]:
if p == p.lower():
color_tag = "b"
else:
color_tag = "w"
# Populate this dictionary with the relevant image paths.
# images[p] = "Images/{0}{1}.png".format(color_tag, p.upper())
images[p] = "https://kivy.org/logos/kivy-logo-black-64.png"
return images
image_dic = loadImages()
game_state = GameState()
class Chessboard(Widget):
def __init__(self, **kwargs):
super(Chessboard, self).__init__(**kwargs)
self.bind(pos=self.drawBoardandPieces)
self.bind(size=self.drawBoardandPieces)
self.drawBoardandPieces()
def drawBoardandPieces(self, *args):
with self.canvas:
# Reset everything in case of redraws.
self.canvas.clear()
for img in self.ids:
img.piece_img.source = ""
img.piece_img.reload()
# Define the lengths of the edges of the squares.
edge_len = min(self.height, self.width) // 8
Config.set("graphics", "resizable", True)
for column in range(0, 8):
for row in range(0, 8):
if ((row + column) % 2) == 0:
graphics.Color(0, 0, 1)
self.dark_rect = graphics.Rectangle(pos=(column*edge_len, row*edge_len), size=(edge_len, edge_len))
else:
graphics.Color(1, 1, 1)
self.light_rect = graphics.Rectangle(pos=(column*edge_len, row*edge_len), size=(edge_len, edge_len))
piece_in_pos = [a[2] for a in game_state.board if (a[0] == column) and (a[1] == row)][0]
if piece_in_pos != "1":
# self.piece_img = Image(source=image_dic[piece_in_pos])
self.piece_img = AsyncImage(source=image_dic[piece_in_pos])
self.piece_img.allow_stretch = True
self.piece_img.keep_ratio = True
self.piece_img.opacity = 1
self.piece_img.pos = (column*edge_len, row*edge_len)
self.piece_img.size = (edge_len, edge_len)
self.add_widget(self.piece_img)
class SCApp(App):
def build(self):
app_layout = BoxLayout(orientation="horizontal")
app_layout.add_widget(widget=Chessboard())
return app_layout
SCApp().run()
The canvas.clear() method only clears canvas instructions, things like Color, Rectangle, etc. It does not affect the list of child widgets (those added using add_widget()). If you are completely redrawing your chess board, then you should probably clear the child widgets as well as clearing the canvas. Try adding:
self.clear_widgets()
along with your canvas.clear().
Thanks to notes from #inclement and #john-anderson, I solved the issue. It turns out that (drawings of[?]) the images appear behind the drawn board, as well, but can't be deleted with self.clear_widgets():
def drawBoardandPieces(self, *args):
with self.canvas:
# Reset everything in case of redraws.
self.canvas.clear()
# Define the lengths of the edges of the squares.
edge_len = min(self.height, self.width) // 8
Config.set("graphics", "resizable", True)
for column in range(0, 8):
for row in range(0, 8):
if ((row + column) % 2) == 0:
graphics.Color(0, 0, 1)
self.dark_rect = graphics.Rectangle(pos=(column*edge_len, row*edge_len), size=(edge_len, edge_len))
else:
graphics.Color(1, 1, 1)
self.light_rect = graphics.Rectangle(pos=(column*edge_len, row*edge_len), size=(edge_len, edge_len))
self.clear_widgets()
for column in range(0, 8):
for row in range(0, 8):
piece_in_pos = [a[2] for a in game_state.board if (a[0] == column) and (a[1] == row)][0]
if piece_in_pos != "1":
self.piece_img = Image(source=image_dic[piece_in_pos])
self.piece_img.allow_stretch = True
self.piece_img.keep_ratio = True
self.piece_img.opacity = 1
self.piece_img.pos = (column*edge_len, row*edge_len)
self.piece_img.size = (edge_len, edge_len)
self.add_widget(self.piece_img)
Related
I am programming a minesweeper and I am stuck because I still have to add a timer. I was able to program one but I can only see it in my console. But i want it to be in my game so that someone who is playong can see the time.
Now how do I add my programmed timer to the game? Down here is my code the first one is for the cell with all the definitions the second one is the main part and the last part is my time. I still have two files called settings and utils but these aren‘t important for the problem…
from tkinter import Button, Label
import random
import settings
import ctypes
import sys
import time
import elapsed
class Cell:
all = []
cell_count = settings.CELL_COUNT
cell_count_label_object = None
def __init__(self,x, y, is_mine=False):
self.is_mine = is_mine
self.is_opened = False
self.is_mine_candidate = False
self.cell_btn_object = False
self.x = x
self.y = y
self.done = False
# Append the object to the Cell.all list
Cell.all.append(self)
def create_btn_object(self, location):
btn = Button(
location,
width=10,
height=3,
)
btn.bind('<Button-1>', self.left_click_actions ) # Left Click
btn.bind('<Button-3>', self.right_click_actions ) # Right Click
self.cell_btn_object = btn
#staticmethod
def create_cell_count_label(location):
lbl = Label(
location,
bg='aquamarine3',
fg='white',
text=f"Cells Left:{Cell.cell_count}",
font=("", 30)
)
Cell.cell_count_label_object = lbl
def left_click_actions(self, event):
if self.is_mine:
self.show_mine()
else:
if self.surrounded_cells_mines_length == 0:
for cell_obj in self.surrounded_cells:
cell_obj.show_cell()
self.show_cell()
# If Mines count is equal to the cells left count, player won
if Cell.cell_count == settings.MINES_COUNT:
ctypes.windll.user32.MessageBoxW(0, 'Congratulations! You won the game!', 'Game Over', 0)
# Cancel Left and Right click events if cell is already opened:
self.cell_btn_object.unbind('<Button-1>')
self.cell_btn_object.unbind('<Button-3>')
def get_cell_by_axis(self, x,y):
# Return a cell object based on the value of x,y
for cell in Cell.all:
if cell.x == x and cell.y == y:
return cell
#property
def surrounded_cells(self):
cells = [
self.get_cell_by_axis(self.x - 1, self.y -1),
self.get_cell_by_axis(self.x - 1, self.y),
self.get_cell_by_axis(self.x - 1, self.y + 1),
self.get_cell_by_axis(self.x, self.y - 1),
self.get_cell_by_axis(self.x + 1, self.y - 1),
self.get_cell_by_axis(self.x + 1, self.y),
self.get_cell_by_axis(self.x + 1, self.y + 1),
self.get_cell_by_axis(self.x, self.y + 1)
]
cells = [cell for cell in cells if cell is not None]
return cells
#property
def surrounded_cells_mines_length(self):
counter = 0
for cell in self.surrounded_cells:
if cell.is_mine:
counter += 1
return counter
def show_cell(self):
if not self.is_opened:
Cell.cell_count -= 1
self.cell_btn_object.configure(text=self.surrounded_cells_mines_length)
# Replace the text of cell count label with the newer count
if Cell.cell_count_label_object:
Cell.cell_count_label_object.configure(
text=f"Cells Left:{Cell.cell_count}"
)
# If this was a mine candidate, then for safety, we should
# configure the background color to SystemButtonFace
self.cell_btn_object.configure(
bg='SystemButtonFace'
)
# Mark the cell as opened (Use is as the last line of this method)
self.is_opened = True
def show_mine(self):
self.cell_btn_object.configure(bg='red')
ctypes.windll.user32.MessageBoxW(0, 'You clicked on a mine', 'Game Over', 0)
sys.exit()
def right_click_actions(self, event):
if not self.is_mine_candidate:
self.cell_btn_object.configure(
text = '🌸',
fg = 'red'
)
self.is_mine_candidate = True
else:
self.cell_btn_object.configure(
bg='SystemButtonFace'
)
self.is_mine_candidate = False
def time():
start_time = time.time()
while True:
if not self.is_opened:
elapsed_time = time.time() - start_time
print(int(elapsed_time))
#staticmethod
def randomize_mines():
picked_cells = random.sample(
Cell.all, settings.MINES_COUNT
)
for picked_cell in picked_cells:
picked_cell.is_mine = True
def __repr__(self):
return f"Cell({self.x}, {self.y})"
from tkinter import *
from cell import Cell
import settings
import utils
import elapsed
import time
root = Tk()
# Override the settings of the window
root.configure(bg="aquamarine3")
root.geometry(f'{settings.WIDTH}x{settings.HEIGHT}')
root.title("Minesweeper Game")
root.resizable(False, False)
top_frame = Frame(
root,
bg='aquamarine3',
width=settings.WIDTH,
height=utils.height_prct(15)
)
top_frame.place(x=0, y=0)
game_title = Label(
top_frame,
bg='aquamarine3',
fg='white',
text='Minesweeper Game',
font=('', 48)
)
game_title.place(
x=utils.width_prct(30), y=0
)
left_frame = Frame(
root,
bg='aquamarine3',
width=utils.width_prct(75),
height=utils.height_prct(75)
)
left_frame.place(x=0, y=utils.height_prct(25))
timer_title = Label(
left_frame,
bg = 'aquamarine3',
fg = 'white',
text = ('time:', command = cell.time)
)
timer_title.place(
x = 0, y = 100
)
center_frame = Frame(
root,
bg='aquamarine3',
width=utils.width_prct(75),
height=utils.height_prct(75)
)
center_frame.place(
x=utils.width_prct(25),
y=utils.height_prct(15),
)
for x in range(settings.GRID_SIZE):
for y in range(settings.GRID_SIZE):
c = Cell(x, y)
c.create_btn_object(center_frame)
c.cell_btn_object.grid(
column=x, row=y
)
# Call the label from the Cell class
Cell.create_cell_count_label(left_frame)
Cell.cell_count_label_object.place(
x=0, y=0
)
Cell.randomize_mines()
# Run the window
root.mainloop()
import time
time.gmtime(0)
start_time = time.time()
def timer():
while True:
elapsed_time = time.time()-start_time
print(int(elapsed_time))
I am attempting to make Minesweeper in python using Tkinter. I have completed all of the initial logic but I am having trouble with the squares with zero surrounding bombs. The program is meant to open all of the surrounding squares when a square with zero surrounding bombs is clicked. The problem here is that it somehow creates an infinite loop. This may be due to the fact that I am calling the function click multiple times using a for loop but I am not sure if this is correct or how to fix it.
My code so far:
import tkinter as tk
from random import choices
from math import floor
##•
def openSurroundings(i):
trash = [i+1, i+8, i+9, i+10, i-1, i-8, i-9, i-10]
for a in trash:
if a<81:
click(floor(a/9), a-((a//9)*9))
def click(row, col):
text = numbers[row][col]
widget = buttons[row][col]
widget.grid_forget()
clickSurrounding = False
if text == 0:
text = ''
clickSurrounding = True
lab = tk.Label(window, text = text, height = 2, width = 5)
lab.grid(row = row, column = col)
if clickSurrounding == True:
openSurroundings((row*9)+col)
def placeBombs():
global widgets, bombs
numOfBombs = 10
widgets = list(range(1, (len(buttons)**2)+1))
bombs = choices(widgets, k = numOfBombs)
def findNumbers():
global numbers
numbers = []
lis_num = []
for i in widgets:
if i in bombs:
lis_num.append('•')
continue
else:
trash = [i+1, i+8, i+9, i+10, i-1, i-8, i-9, i-10]
num = 0
for a in trash:
if a > 0 and a in bombs:
num += 1
lis_num.append(num)
for i in range(0, len(lis_num), 9):
numbers.append(lis_num[i:i + 9])
window = tk.Tk()
window.title('Minesweeper')
sideLen = 9
row_index = 0
cell_index = 0
buttons = []
while row_index != sideLen:
button_row = []
while cell_index != sideLen:
button = tk.Button(window, width=5, height = 2, command=lambda row_index=row_index, cell_index=cell_index: click(row_index, cell_index))
button_row.append(button)
button.grid(row=row_index, column=cell_index)
cell_index += 1
buttons.append(button_row)
cell_index = 0
row_index += 1
placeBombs()
findNumbers()
Kivy Gui have a transition animation to switch between windows (going back and forth also) we can do it easily in kivy. But in PyQt5 I did't find out any way to transit between window (with animation) and going back and forth to a window again and again is also not working. So, is there any way to do like Kivy do transitions, going back and forth to a window easily in PyQt5.
Qt doesn't provide a similar effect on its own, but it still can be achieved using a subclass of a QStackedWidget (which behaves similarly to a QTabWidget, but without any QTabBar).
In the following example I'll show you how to implement a basic "swap" transition between two widgets that are added to a QStackedWidget, the next widget will scroll from right to left if the index is greater than the current, and vice versa.
class TransitionWidget(QtWidgets.QStackedWidget):
_nextIndex = _nextWidget = None
_orientation = QtCore.Qt.Horizontal
def __init__(self):
super().__init__()
self._animation = QtCore.QVariantAnimation(
startValue=0., endValue=1., duration=250)
self._animation.valueChanged.connect(self._aniUpdate)
self._animation.finished.connect(self._aniFinished)
self._animation.setEasingCurve(QtCore.QEasingCurve.InOutQuart)
def setDuration(self, duration):
self._animation.setDuration(duration)
def setCurve(self, curve):
if isinstance(curve, QtCore.QEasingCurve):
self._animation.setEasingCurve(curve)
def setOrientation(self, orientation):
self._orientation = orientation
def getRange(self, prevIndex, nextIndex):
rect = self.rect()
currentStart = nextEnd = QtCore.QPoint()
if self._orientation == QtCore.Qt.Horizontal:
if prevIndex < nextIndex:
currentEnd = QtCore.QPoint(-rect.width(), 0)
nextStart = QtCore.QPoint(rect.width(), 0)
else:
currentEnd = QtCore.QPoint(rect.width(), 0)
nextStart = QtCore.QPoint(-rect.width(), 0)
else:
if prevIndex < nextIndex:
currentEnd = QtCore.QPoint(0, -rect.width())
nextStart = QtCore.QPoint(0, rect.width())
else:
currentEnd = QtCore.QPoint(0, rect.width())
nextStart = QtCore.QPoint(0, -rect.width())
return currentStart, currentEnd, nextStart, nextEnd
def setCurrentIndex(self, index):
if index == self.currentIndex():
return
# prepare the next widget changes
if self._nextWidget is not None:
self._nextWidget.hide()
self._nextIndex = index
self._nextWidget = self.widget(index)
self._nextWidget.show()
rect = self.rect()
rect.translate(self.rect().topRight())
self._nextWidget.setGeometry(rect)
self._nextWidget.raise_()
self._animation.start()
def _aniFinished(self):
super().setCurrentIndex(self._nextIndex)
self._nextIndex = self._nextWidget = None
def _aniUpdate(self, value):
if not self._animation.state():
return
currentStart, currentEnd, nextStart, nextEnd = self.getRange(self.currentIndex(), self._nextIndex)
rect = self.rect()
self.currentWidget().setGeometry(rect.translated(QtCore.QLineF(currentStart, currentEnd).pointAt(value).toPoint()))
self._nextWidget.setGeometry(rect.translated(QtCore.QLineF(nextStart, nextEnd).pointAt(value).toPoint()))
self.update()
Example code:
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
mainWidget = QtWidgets.QWidget()
mainLayout = QtWidgets.QHBoxLayout(mainWidget)
transitionWidget = TransitionWidget()
mainLayout.addWidget(transitionWidget)
pageCount = 10
for page in range(pageCount):
widget = QtWidgets.QWidget()
layout = QtWidgets.QGridLayout(widget)
pageLabel = QtWidgets.QLabel('Page {}'.format(page + 1))
layout.addWidget(pageLabel, 0, 0, 1, 2)
prevBtn = QtWidgets.QPushButton('Previous')
if not page:
prevBtn.setEnabled(False)
layout.addWidget(prevBtn)
nextBtn = QtWidgets.QPushButton('Next')
layout.addWidget(nextBtn)
if page == pageCount - 1:
nextBtn.setEnabled(False)
transitionWidget.addWidget(widget)
prevBtn.clicked.connect(lambda _, page=page: transitionWidget.setCurrentIndex(page - 1))
nextBtn.clicked.connect(lambda _, page=page: transitionWidget.setCurrentIndex(page + 1))
sep = QtWidgets.QFrame(frameShape=QtWidgets.QFrame.VLine)
mainLayout.addWidget(sep)
orientationCombo = QtWidgets.QComboBox()
orientationLayout = QtWidgets.QFormLayout()
mainLayout.addLayout(orientationLayout)
orientationCombo.addItems(['Horizontal', 'Vertical'])
orientationCombo.currentIndexChanged.connect(lambda o: transitionWidget.setOrientation(o + 1))
orientationLayout.addRow('Orientation', orientationCombo)
durationSpin = QtWidgets.QSpinBox(minimum=50, maximum=1000, singleStep=50, suffix='ms')
orientationLayout.addRow('Duration', durationSpin)
durationSpin.setValue(transitionWidget._animation.duration())
durationSpin.valueChanged.connect(transitionWidget.setDuration)
mainWidget.show()
sys.exit(app.exec_())
so I'm new to Python and have to do a project where we make an interface that generates turtle figures using a tkinter GUI. 20% of our marks go for personal contribution to the interface so I want to be able to change the color of the turtle pen by selecting from an option menu, e.g. when 'Binary Tree' is selected you can choose red and it will draw in red rather than the default black. I'm after spending the bones of 8 hours so far trying to get this to work. Can someone please help me or tell me if it's possible to do? Here's my code so far:
# Import the Modules
from turtle import *
from tkinter import *
from tkinter.ttk import Entry, OptionMenu
import math
library = ["Binary Tree", "Dandelion", "Fern", "Flake", "Square Gasket", "Swiss Flag", "Square Gasket", "Circle Gasket"]
colorLibrary = ["black", "red", "blue", "green", "cyan", "magenta", "white", "yellow"]
#Create an empty window and give it's width and height
root = Tk()
root.title("Turtle Fractals")
root.geometry("400x200+300+300")
#Set the pen speed & width
pen = Pen()
pen.speed(0)
pen.width(1)
#end def
screen = Screen()
screen.bgcolor("grey")
#===================================
# Event handler functions
#===================================
def clearF() :
#Empty the entry vars
lengthStr.set("")
fractalStr.set("")
screen.reset()
#End def
pen.goto(0,0)
def drawF() :
# get the string and make it an integer
age = int(fractalStr.get())
length = int(lengthStr.get())
graphics = library.index(libStr.get())
if graphics == 0 :
binTree (age, length);
elif graphics == 1 :
dandelion (age, length);
elif graphics == 2 :
fern (age, length);
elif graphics == 3 :
flake (age,length);
elif graphics == 4 :
sGasket (age,length);
elif graphics == 5 :
swissFlag (age, length);
elif graphics == 6 :
squareGasket (age, length);
elif graphics == 7 :
circleGasket (age, length);
pen = colorLibrary.index(colorLibStr.get())
if pen == 0 :
black();
elif pen == 1 :
red();
elif pen == 2 :
blue();
elif pen == 3 :
green();
elif pen == 4 :
cyan();
elif pen == 5 :
magenta();
elif pen == 6 :
white();
elif pen == 7 :
yellow();
#End elif
#End def
def black():
color = Color(000,000,000)
def red():
color = Color(255,000,000)
def blue():
color = Color("blue")
def green():
color = Color("Green")
def cyan():
color = Color("Cyan")
def magenta():
color = Color("Magenta")
def white():
color = Color("White")
def yellow():
color = Color("Yellow")
#Draw the Binary Tree
def binTree(n,l) :
if n==0 or l<2 :
return
#End if
pen.forward(l)
pen.left(45); binTree(n-1, l/2)
pen.right(90); binTree(n-1, l/2); pen.left(45)
pen.backward(l)
color = colorLibrary
#End def
#Draw the Dandelion
def dandelion(n,l) :
if n==0 or l<2 :
return
#End if
pen.forward(l)
pen.left(90); dandelion(n-1, l/3)
pen.right(60); dandelion(n-1, l/3)
pen.right(60); dandelion(n-1, l/3)
pen.right(60); dandelion(n-1, l/3)
pen.left(90)
pen.backward(l)
#End def
#Draw the Fern
def fern (n,l) :
if n==0 or l<2 :
return
#End if
pen.forward(2*l/3)
pen.right(50); fern(n-1, l/2); pen.left(50)
pen.forward(2*l/3)
pen.left(30); fern(n-1, l/2); pen.right(30)
pen.forward(2*l/3)
pen.right(15); fern(n-1, 0.8*l); pen.left(15)
pen.backward(2*l)
#End def
#Draw the Koch curve
def koch(n,l) :
if n==0 or l<2 :
pen.forward(l)
return
#End if
koch(n-1, l/3); pen.left(60)
koch(n-1, l/3); pen.right(120)
koch(n-1, l/3); pen.left(60)
koch(n-1, l/3)
#End def
#Draw the Snowflake
def flake(n,l) :
for i in range(3) :
koch(n,l)
pen.right(120)
#End for
#End def
#Draw the Sierpinski Gasket
def sGasket(n,l) :
if n==0 or l<2 :
for i in range(3) :
pen.forward(l)
pen.left(120)
return
#End for
#End if
for i in range(3) :
sGasket(n-1, l/3)
pen.forward(l)
pen.left(120)
#End for
#End def
# Swiss Flag
def swissFlag(n,l):
if n == 0 or l < 2:
for i in range(4):
pen.forward(l)
pen.left(90)
#endfor
return
#endif
for i in range(4):
swissFlag(n - 1, l / 3)
pen.forward(l)
pen.left(90)
#endfor
#end def
# Square gasket
def squareGasket(n,l):
if n == 0 or l < 2:
for i in range(4):
pen.forward(l)
pen.left(90)
#endfor
return
#endif
for i in range(4):
squareGasket(n - 1, l / 3)
pen.forward(l)
pen.left(90)
pen.forward(l / 3);pen.left(90);pen.forward(l / 3);pen.right(90);
squareGasket(n - 1, l / 3)
pen.right(90);pen.forward(l / 3);pen.left(90);pen.backward(l/3)
#endfor
#end
# Circle gasket
def circleGasket(n,l):
if n == 0 or l<2:
return
#endif
for i in range(2):
circleGasket(n - 1, l / 2)
pen.circle(l, 90)
circleGasket(n - 1, l / 3)
pen.circle(l, 90)
#end
#===================================
# Make the interface components
#===================================
label = Label(root, text = "Turtle Fractals")
label.grid(row = 0, column = 1, columnspan = 2)
fractalLabel = Label(root, text = "Fractal")
fractalLabel.grid(row = 1, column = 0)
fractalStr = StringVar()
fractalEntry = Entry(root, textvariable = fractalStr)
fractalEntry.grid(row = 1, column = 1)
libStr = StringVar()
libOptionMenu = OptionMenu(root, libStr, library[0], *library)
libOptionMenu.grid(row = 1, column = 3, columnspan = 2)
colorLibStr = StringVar()
colorLibOptionMenu = OptionMenu(root, colorLibStr, colorLibrary[0], *colorLibrary)
colorLibOptionMenu.grid(row = 2, column = 3, columnspan = 2)
#================
lengthLabel = Label(root, text = "Length")
lengthLabel.grid(row = 2, column = 0)
lengthStr = StringVar()
lengthEntry = Entry(root, textvariable = lengthStr)
lengthEntry.grid(row = 2, column = 1)
clearButton = Button(root, text = "Clear", command = clearF)
clearButton.grid(row = 3, column = 1, columnspan = 2)
drawButton = Button(root, text = "Draw", command = drawF)
drawButton.grid(row = 3, column = 3)
#=====================Catch Events===================
root.mainloop()
Apologies for the state of my code. I'm going to clean it up and comment more once I get this bit done. Thanks in advance.
Yes, you can turtle.pencolor().
from tkinter import *
from random import *
from functools import partial
class Game:
def __init__(self):
self.root = Tk()
self.frame = Frame(width = 574, height = 574)
self.frame.grid(columnspan = 30, rowspan = 30)
self.minex = []
self.miney = []
self.clickx = 0
self.clicky = 0
blank = PhotoImage(file = 'C:\\Users\\PC\\Desktop\\Python Programs\\Minesweeper\\blank.gif')
for i in range(0,30):
for j in range(0,30):
button = Button(width = 15, height = 15, padx = 2, pady = 2, image = blank, command = partial(self.click, j, i))
button.grid(row = i, column = j)
self.mine_place()
self.root.mainloop()
def mine_place(self):
for i in range(0,15):
self.minex.append(randint(1,30))
self.miney.append(randint(1,30))
def click(self, j, i):
miss = PhotoImage(file = 'C:\\Users\\PC\\Desktop\\Python Programs\\Minesweeper\\miss.gif')
hit = PhotoImage(file = 'C:\\Users\\PC\\Desktop\\Python Programs\\Minesweeper\\hit.gif')
for k in range(0, len(self.minex)):
if j + 1 == self.minex[k] and i + 1 == self.miney[k]:
button = Button(image = hit)
button.grid(row = i, column = j)
else:
button = Button(image = miss)
button.grid(row = i, column = j)
app = Game()
In self.click, when I wish to create a button with this image I am given a blank image. If I create a button in init, the image comes out just fine. What is wrong?..............................................................
It looks like you're images are getting garbage collected you need to save a reference to the images after using PhotoImage.
ie - you create the image blank so save a reference as self.blank= blank and use image = self.hit