Cleaning up the repo a bit by removing older folders
Before Width: | Height: | Size: 184 KiB |
|
@ -1,233 +0,0 @@
|
|||
import PySimpleGUI as sg
|
||||
import os
|
||||
import sys
|
||||
import chess
|
||||
import chess.pgn
|
||||
import copy
|
||||
import chess.uci
|
||||
|
||||
CHESS_PATH = '.' # path to the chess pieces
|
||||
|
||||
BLANK = 0 # piece names
|
||||
PAWNB = 1
|
||||
KNIGHTB = 2
|
||||
BISHOPB = 3
|
||||
ROOKB = 4
|
||||
KINGB = 5
|
||||
QUEENB = 6
|
||||
PAWNW = 7
|
||||
KNIGHTW = 8
|
||||
BISHOPW = 9
|
||||
ROOKW = 10
|
||||
KINGW = 11
|
||||
QUEENW = 12
|
||||
|
||||
initial_board = [[ROOKB, KNIGHTB, BISHOPB, QUEENB, KINGB, BISHOPB, KNIGHTB, ROOKB],
|
||||
[PAWNB, ] * 8,
|
||||
[BLANK, ] * 8,
|
||||
[BLANK, ] * 8,
|
||||
[BLANK, ] * 8,
|
||||
[BLANK, ] * 8,
|
||||
[PAWNW, ] * 8,
|
||||
[ROOKW, KNIGHTW, BISHOPW, QUEENW, KINGW, BISHOPW, KNIGHTW, ROOKW]]
|
||||
|
||||
blank = os.path.join(CHESS_PATH, 'blank.png')
|
||||
bishopB = os.path.join(CHESS_PATH, 'nbishopb.png')
|
||||
bishopW = os.path.join(CHESS_PATH, 'nbishopw.png')
|
||||
pawnB = os.path.join(CHESS_PATH, 'npawnb.png')
|
||||
pawnW = os.path.join(CHESS_PATH, 'npawnw.png')
|
||||
knightB = os.path.join(CHESS_PATH, 'nknightb.png')
|
||||
knightW = os.path.join(CHESS_PATH, 'nknightw.png')
|
||||
rookB = os.path.join(CHESS_PATH, 'nrookb.png')
|
||||
rookW = os.path.join(CHESS_PATH, 'nrookw.png')
|
||||
queenB = os.path.join(CHESS_PATH, 'nqueenb.png')
|
||||
queenW = os.path.join(CHESS_PATH, 'nqueenw.png')
|
||||
kingB = os.path.join(CHESS_PATH, 'nkingb.png')
|
||||
kingW = os.path.join(CHESS_PATH, 'nkingw.png')
|
||||
|
||||
images = {BISHOPB: bishopB, BISHOPW: bishopW, PAWNB: pawnB, PAWNW: pawnW, KNIGHTB: knightB, KNIGHTW: knightW,
|
||||
ROOKB: rookB, ROOKW: rookW, KINGB: kingB, KINGW: kingW, QUEENB: queenB, QUEENW: queenW, BLANK: blank}
|
||||
|
||||
|
||||
def open_pgn_file(filename):
|
||||
pgn = open(filename)
|
||||
first_game = chess.pgn.read_game(pgn)
|
||||
moves = [move for move in first_game.main_line()]
|
||||
return moves
|
||||
|
||||
|
||||
def render_square(image, key, location):
|
||||
if (location[0] + location[1]) % 2:
|
||||
color = '#B58863'
|
||||
else:
|
||||
color = '#F0D9B5'
|
||||
return sg.RButton('', image_filename=image, size=(1, 1), button_color=('white', color), pad=(0, 0), key=key)
|
||||
|
||||
|
||||
def redraw_board(window, board):
|
||||
for i in range(8):
|
||||
for j in range(8):
|
||||
color = '#B58863' if (i + j) % 2 else '#F0D9B5'
|
||||
piece_image = images[board[i][j]]
|
||||
elem = window.FindElement(key=(i, j))
|
||||
elem.Update(button_color=('white', color),
|
||||
image_filename=piece_image, )
|
||||
|
||||
|
||||
def PlayGame():
|
||||
menu_def = [['&File', ['&Open PGN File', 'E&xit']],
|
||||
['&Help', '&About...'], ]
|
||||
|
||||
# sg.SetOptions(margins=(0,0))
|
||||
sg.ChangeLookAndFeel('GreenTan')
|
||||
# create initial board setup
|
||||
psg_board = copy.deepcopy(initial_board)
|
||||
# the main board display layout
|
||||
board_layout = [[sg.T(' ')] + [sg.T('{}'.format(a), pad=((23, 27), 0), font='Any 13') for a in 'abcdefgh']]
|
||||
# loop though board and create buttons with images
|
||||
for i in range(8):
|
||||
row = [sg.T(str(8 - i) + ' ', font='Any 13')]
|
||||
for j in range(8):
|
||||
piece_image = images[psg_board[i][j]]
|
||||
row.append(render_square(piece_image, key=(i, j), location=(i, j)))
|
||||
row.append(sg.T(str(8 - i) + ' ', font='Any 13'))
|
||||
board_layout.append(row)
|
||||
# add the labels across bottom of board
|
||||
board_layout.append([sg.T(' ')] + [sg.T('{}'.format(a), pad=((23, 27), 0), font='Any 13') for a in 'abcdefgh'])
|
||||
|
||||
# setup the controls on the right side of screen
|
||||
openings = (
|
||||
'Any', 'Defense', 'Attack', 'Trap', 'Gambit', 'Counter', 'Sicillian', 'English', 'French', 'Queen\'s openings',
|
||||
'King\'s Openings', 'Indian Openings')
|
||||
|
||||
board_controls = [[sg.RButton('New Game', key='New Game'), sg.RButton('Draw')],
|
||||
[sg.RButton('Resign Game'), sg.RButton('Set FEN')],
|
||||
[sg.RButton('Player Odds'), sg.RButton('Training')],
|
||||
[sg.Drop(openings), sg.Text('Opening/Style')],
|
||||
[sg.CBox('Play As White', key='_white_')],
|
||||
[sg.Drop([2, 3, 4, 5, 6, 7, 8, 9, 10], size=(3, 1), key='_level_'), sg.Text('Difficulty Level')],
|
||||
[sg.Text('Move List')],
|
||||
[sg.Multiline([], do_not_clear=True, autoscroll=True, size=(15, 10), key='_movelist_')],
|
||||
]
|
||||
|
||||
# layouts for the tabs
|
||||
controls_layout = [[sg.Text('Performance Parameters', font='_ 20')],
|
||||
[sg.T('Put stuff like AI engine tuning parms on this tab')]]
|
||||
|
||||
statistics_layout = [[sg.Text('Statistics', font=('_ 20'))],
|
||||
[sg.T('Game statistics go here?')]]
|
||||
|
||||
board_tab = [[sg.Column(board_layout)]]
|
||||
|
||||
# the main window layout
|
||||
layout = [[sg.Menu(menu_def, tearoff=False)],
|
||||
[sg.TabGroup([[sg.Tab('Board', board_tab),
|
||||
sg.Tab('Controls', controls_layout),
|
||||
sg.Tab('Statistics', statistics_layout)]], title_color='red'),
|
||||
sg.Column(board_controls)],
|
||||
[sg.Text('Click anywhere on board for next move', font='_ 14')]]
|
||||
|
||||
window = sg.Window('Chess',
|
||||
default_button_element_size=(12, 1),
|
||||
auto_size_buttons=False,
|
||||
icon='kingb.ico').Layout(layout)
|
||||
|
||||
filename = sg.PopupGetFile('\n'.join(('To begin, set location of AI EXE file',
|
||||
'If you have not done so already, download the engine',
|
||||
'Download the StockFish Chess engine at: https://stockfishchess.org/download/')),
|
||||
file_types=(('Chess AI Engine EXE File', '*.exe'),))
|
||||
if filename is None:
|
||||
sys.exit()
|
||||
engine = chess.uci.popen_engine(filename)
|
||||
engine.uci()
|
||||
info_handler = chess.uci.InfoHandler()
|
||||
engine.info_handlers.append(info_handler)
|
||||
|
||||
board = chess.Board()
|
||||
move_count = 1
|
||||
move_state = move_from = move_to = 0
|
||||
# ---===--- Loop taking in user input --- #
|
||||
while not board.is_game_over():
|
||||
|
||||
if board.turn == chess.WHITE:
|
||||
engine.position(board)
|
||||
|
||||
# human_player(board)
|
||||
move_state = 0
|
||||
while True:
|
||||
button, value = window.Read()
|
||||
if button in (None, 'Exit'):
|
||||
exit()
|
||||
if button == 'New Game':
|
||||
sg.Popup('You have to restart the program to start a new game... sorry....')
|
||||
break
|
||||
psg_board = copy.deepcopy(initial_board)
|
||||
redraw_board(window, psg_board)
|
||||
move_state = 0
|
||||
break
|
||||
level = value['_level_']
|
||||
if type(button) is tuple:
|
||||
if move_state == 0:
|
||||
move_from = button
|
||||
row, col = move_from
|
||||
piece = psg_board[row][col] # get the move-from piece
|
||||
button_square = window.FindElement(key=(row, col))
|
||||
button_square.Update(button_color=('white', 'red'))
|
||||
move_state = 1
|
||||
elif move_state == 1:
|
||||
move_to = button
|
||||
row, col = move_to
|
||||
if move_to == move_from: # cancelled move
|
||||
color = '#B58863' if (row + col) % 2 else '#F0D9B5'
|
||||
button_square.Update(button_color=('white', color))
|
||||
move_state = 0
|
||||
continue
|
||||
|
||||
picked_move = '{}{}{}{}'.format('abcdefgh'[move_from[1]], 8 - move_from[0],
|
||||
'abcdefgh'[move_to[1]], 8 - move_to[0])
|
||||
|
||||
if picked_move in [str(move) for move in board.legal_moves]:
|
||||
board.push(chess.Move.from_uci(picked_move))
|
||||
else:
|
||||
print('Illegal move')
|
||||
move_state = 0
|
||||
color = '#B58863' if (move_from[0] + move_from[1]) % 2 else '#F0D9B5'
|
||||
button_square.Update(button_color=('white', color))
|
||||
continue
|
||||
|
||||
psg_board[move_from[0]][move_from[1]] = BLANK # place blank where piece was
|
||||
psg_board[row][col] = piece # place piece in the move-to square
|
||||
redraw_board(window, psg_board)
|
||||
move_count += 1
|
||||
|
||||
window.FindElement('_movelist_').Update(picked_move + '\n', append=True)
|
||||
|
||||
break
|
||||
else:
|
||||
engine.position(board)
|
||||
best_move = engine.go(searchmoves=board.legal_moves, depth=level, movetime=(level * 100)).bestmove
|
||||
move_str = str(best_move)
|
||||
from_col = ord(move_str[0]) - ord('a')
|
||||
from_row = 8 - int(move_str[1])
|
||||
to_col = ord(move_str[2]) - ord('a')
|
||||
to_row = 8 - int(move_str[3])
|
||||
|
||||
window.FindElement('_movelist_').Update(move_str + '\n', append=True)
|
||||
|
||||
piece = psg_board[from_row][from_col]
|
||||
psg_board[from_row][from_col] = BLANK
|
||||
psg_board[to_row][to_col] = piece
|
||||
redraw_board(window, psg_board)
|
||||
|
||||
board.push(best_move)
|
||||
move_count += 1
|
||||
sg.Popup('Game over!', 'Thank you for playing')
|
||||
|
||||
|
||||
# Download the StockFish Chess engine at: https://stockfishchess.org/download/
|
||||
# engine = chess.uci.popen_engine(r'E:\DownloadsE\stockfish-9-win\Windows\stockfish_9_x64.exe')
|
||||
# engine.uci()
|
||||
# info_handler = chess.uci.InfoHandler()
|
||||
# engine.info_handlers.append(info_handler)
|
||||
# level = 2
|
||||
PlayGame()
|
|
@ -1,160 +0,0 @@
|
|||
import PySimpleGUI as sg
|
||||
import os
|
||||
import chess
|
||||
import chess.pgn
|
||||
import copy
|
||||
import time
|
||||
|
||||
button_names = ('close', 'cookbook', 'cpu', 'github', 'pysimplegui', 'run', 'storage', 'timer')
|
||||
|
||||
CHESS_PATH = '.' # path to the chess pieces
|
||||
|
||||
BLANK = 0 # piece names
|
||||
PAWNB = 1
|
||||
KNIGHTB = 2
|
||||
BISHOPB = 3
|
||||
ROOKB = 4
|
||||
KINGB = 5
|
||||
QUEENB = 6
|
||||
PAWNW = 7
|
||||
KNIGHTW = 8
|
||||
BISHOPW = 9
|
||||
ROOKW = 10
|
||||
KINGW = 11
|
||||
QUEENW = 12
|
||||
|
||||
initial_board = [[ROOKB, KNIGHTB, BISHOPB, KINGB, QUEENB, BISHOPB, KNIGHTB, ROOKB ],
|
||||
[PAWNB,]*8,
|
||||
[BLANK,]*8,
|
||||
[BLANK,]*8,
|
||||
[BLANK,]*8,
|
||||
[BLANK,]*8,
|
||||
[PAWNW,]*8,
|
||||
[ROOKW, KNIGHTW, BISHOPW, KINGW, QUEENW, BISHOPW, KNIGHTW, ROOKW]]
|
||||
|
||||
blank = os.path.join(CHESS_PATH, 'blank.png')
|
||||
bishopB = os.path.join(CHESS_PATH, 'nbishopb.png')
|
||||
bishopW = os.path.join(CHESS_PATH, 'nbishopw.png')
|
||||
pawnB = os.path.join(CHESS_PATH, 'npawnb.png')
|
||||
pawnW = os.path.join(CHESS_PATH, 'npawnw.png')
|
||||
knightB = os.path.join(CHESS_PATH, 'nknightb.png')
|
||||
knightW = os.path.join(CHESS_PATH, 'nknightw.png')
|
||||
rookB = os.path.join(CHESS_PATH, 'nrookb.png')
|
||||
rookW = os.path.join(CHESS_PATH, 'nrookw.png')
|
||||
queenB = os.path.join(CHESS_PATH, 'nqueenB.png')
|
||||
queenW = os.path.join(CHESS_PATH, 'nqueenW.png')
|
||||
kingB = os.path.join(CHESS_PATH, 'nkingb.png')
|
||||
kingW = os.path.join(CHESS_PATH, 'nkingw.png')
|
||||
|
||||
images = {BISHOPB: bishopB, BISHOPW: bishopW, PAWNB: pawnB, PAWNW: pawnW, KNIGHTB: knightB, KNIGHTW: knightW,
|
||||
ROOKB: rookB, ROOKW: rookW, KINGB: kingB, KINGW: kingW, QUEENB: queenB, QUEENW: queenW, BLANK: blank}
|
||||
|
||||
def open_pgn_file(filename):
|
||||
pgn = open(filename)
|
||||
first_game = chess.pgn.read_game(pgn)
|
||||
moves = [move for move in first_game.main_line()]
|
||||
return moves
|
||||
|
||||
def render_square(image, key, location):
|
||||
if (location[0] + location[1]) % 2:
|
||||
color = '#B58863'
|
||||
else:
|
||||
color = '#F0D9B5'
|
||||
return sg.RButton('', image_filename=image, size=(1, 1), button_color=('white', color), pad=(0, 0), key=key)
|
||||
|
||||
def redraw_board(window, board):
|
||||
for i in range(8):
|
||||
for j in range(8):
|
||||
color = '#B58863' if (i+j) % 2 else '#F0D9B5'
|
||||
piece_image = images[board[i][j]]
|
||||
elem = window.FindElement(key=(i,j))
|
||||
elem.Update(button_color = ('white', color),
|
||||
image_filename=piece_image,)
|
||||
|
||||
def PlayGame():
|
||||
|
||||
menu_def = [['&File', ['&Open PGN File', 'E&xit' ]],
|
||||
['&Help', '&About...'],]
|
||||
|
||||
# sg.SetOptions(margins=(0,0))
|
||||
sg.ChangeLookAndFeel('GreenTan')
|
||||
# create initial board setup
|
||||
board = copy.deepcopy(initial_board)
|
||||
# the main board display layout
|
||||
board_layout = [[sg.T(' ')] + [sg.T('{}'.format(a), pad=((23,27),0), font='Any 13') for a in 'abcdefgh']]
|
||||
# loop though board and create buttons with images
|
||||
for i in range(8):
|
||||
row = [sg.T(str(8-i)+' ', font='Any 13')]
|
||||
for j in range(8):
|
||||
piece_image = images[board[i][j]]
|
||||
row.append(render_square(piece_image, key=(i,j), location=(i,j)))
|
||||
row.append(sg.T(str(8-i)+' ', font='Any 13'))
|
||||
board_layout.append(row)
|
||||
# add the labels across bottom of board
|
||||
board_layout.append([sg.T(' ')] + [sg.T('{}'.format(a), pad=((23,27),0), font='Any 13') for a in 'abcdefgh'])
|
||||
|
||||
# setup the controls on the right side of screen
|
||||
openings = ('Any', 'Defense', 'Attack', 'Trap', 'Gambit','Counter', 'Sicillian', 'English','French', 'Queen\'s openings', 'King\'s Openings','Indian Openings')
|
||||
|
||||
board_controls = [[sg.RButton('New Game', key='Open PGN File'), sg.RButton('Draw')],
|
||||
[sg.RButton('Resign Game'), sg.RButton('Set FEN')],
|
||||
[sg.RButton('Player Odds'),sg.RButton('Training') ],
|
||||
[sg.Drop(openings),sg.Text('Opening/Style')],
|
||||
[sg.CBox('Play a White', key='_white_')],
|
||||
[sg.Text('Move List')],
|
||||
[sg.Multiline([], do_not_clear=True, autoscroll=True, size=(15,10),key='_movelist_')],]
|
||||
|
||||
# layouts for the tabs
|
||||
controls_layout = [[sg.Text('Performance Parameters', font='_ 20')],
|
||||
[sg.T('Put stuff like AI engine tuning parms on this tab')]]
|
||||
|
||||
statistics_layout = [[sg.Text('Statistics', font=('_ 20'))],
|
||||
[sg.T('Game statistics go here?')]]
|
||||
|
||||
board_tab = [[sg.Column(board_layout)]]
|
||||
|
||||
# the main window layout
|
||||
layout = [[sg.Menu(menu_def, tearoff=False)],
|
||||
[sg.TabGroup([[sg.Tab('Board',board_tab),
|
||||
sg.Tab('Controls', controls_layout),
|
||||
sg.Tab('Statistics', statistics_layout)]], title_color='red'),
|
||||
sg.Column(board_controls)],
|
||||
[sg.Text('Click anywhere on board for next move', font='_ 14')]]
|
||||
|
||||
window = sg.Window('Chess', default_button_element_size=(12,1), auto_size_buttons=False, icon='kingb.ico').Layout(layout)
|
||||
|
||||
# ---===--- Loop taking in user input --- #
|
||||
i = 0
|
||||
moves = None
|
||||
while True:
|
||||
button, value = window.Read()
|
||||
if button in (None, 'Exit'):
|
||||
break
|
||||
if button == 'Open PGN File':
|
||||
filename = sg.PopupGetFile('', no_window=True)
|
||||
if filename is not None:
|
||||
moves = open_pgn_file(filename)
|
||||
i = 0
|
||||
board = copy.deepcopy(initial_board)
|
||||
window.FindElement('_movelist_').Update(value='')
|
||||
if button == 'About...':
|
||||
sg.Popup('Powerd by Engine Kibitz Chess Engine')
|
||||
if type(button) is tuple and moves is not None and i < len(moves):
|
||||
move = moves[i] # get the current move
|
||||
window.FindElement('_movelist_').Update(value='{} {}\n'.format(i+1, str(move)), append=True)
|
||||
move_from = move.from_square # parse the move-from and move-to squares
|
||||
move_to = move.to_square
|
||||
row, col = move_from // 8, move_from % 8
|
||||
piece = board[row][col] # get the move-from piece
|
||||
button = window.FindElement(key=(row,col))
|
||||
for x in range(3):
|
||||
button.Update(button_color = ('white' , 'red' if x % 2 else 'white'))
|
||||
window.Refresh()
|
||||
time.sleep(.05)
|
||||
board[row][col] = BLANK # place blank where piece was
|
||||
row, col = move_to // 8, move_to % 8 # compute move-to square
|
||||
board[row][col] = piece # place piece in the move-to square
|
||||
redraw_board(window, board)
|
||||
i += 1
|
||||
|
||||
PlayGame()
|
Before Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.9 KiB |
BIN
Chess/blank.png
Before Width: | Height: | Size: 1.2 KiB |
|
@ -1,36 +0,0 @@
|
|||
[Event "Wch U12"]
|
||||
[Site "Duisburg"]
|
||||
[Date "1992.??.??"]
|
||||
[Round "1"]
|
||||
[White "Malakhov, Vladimir"]
|
||||
[Black "Ab Rahman, M."]
|
||||
[Result "1-0"]
|
||||
[WhiteElo ""]
|
||||
[BlackElo ""]
|
||||
[ECO "A05"]
|
||||
|
||||
1.Nf3 Nf6 2.b3 g6 3.Bb2 Bg7 4.g3 d6 5.Bg2 O-O 6.O-O c6 7.d3 e5 8.c4 Ne8 9.Nbd2 f5
|
||||
10.Qc2 Na6 11.c5 Nxc5 12.Nxe5 Qe7 13.d4 Na6 14.Qc4+ Kh8 15.Nef3 Be6 16.Qc3 f4
|
||||
17.gxf4 Rxf4 18.Qe3 Rf8 19.Ng5 Nec7 20.Nc4 Rae8 21.Nxe6 Qxe6 22.Qxe6 Rxe6
|
||||
23.e3 d5 24.Ne5 g5 25.Ba3 Rff6 26.Bh3 Re8 27.Bd7 Rd8 28.Be7 Rxd7 29.Bxf6 1-0
|
||||
|
||||
|
||||
[Event "Wch U12"]
|
||||
[Site "Duisburg"]
|
||||
[Date "1992.??.??"]
|
||||
[Round "2"]
|
||||
[White "Malakhov, Vladimir"]
|
||||
[Black "Berescu, Alin"]
|
||||
[Result "1-0"]
|
||||
[WhiteElo ""]
|
||||
[BlackElo ""]
|
||||
[ECO "D05"]
|
||||
|
||||
1.d4 Nf6 2.Nd2 d5 3.Ngf3 e6 4.e3 c5 5.c3 Nbd7 6.Bd3 Bd6 7.O-O O-O 8.Re1 b6
|
||||
9.e4 dxe4 10.Nxe4 Be7 11.Ne5 Bb7 12.Ng5 g6 13.Qe2 Nxe5 14.dxe5 Nh5 15.Ne4 Qd5
|
||||
16.f4 Rfd8 17.Bc2 Qc6 18.Be3 Rd7 19.Rad1 Rad8 20.Rxd7 Rxd7 21.Nd2 Ng7 22.Be4 Qc8
|
||||
23.g4 Qd8 24.Bxb7 Rxb7 25.Ne4 Rd7 26.c4 h5 27.h3 h4 28.Kh2 Ne8 29.f5 Qc7
|
||||
30.Bf4 Rd4 31.Qf2 Rxc4 32.f6 Qb7 33.Ng5 Bf8 34.b3 Rc3 35.Qd2 Rf3 36.Nxf3 Qxf3
|
||||
37.Qe3 Qd5 38.Qe4 Qd7 39.Qf3 Nc7 40.Rd1 Nd5 41.Bg5 Qc7 42.Re1 b5 43.Qd1 c4
|
||||
44.Qc1 Bb4 45.Bd2 Bxd2 46.Qxd2 Nxf6 47.bxc4 bxc4 48.Qd6 Qa5 49.Rf1 Nd5 50.Qd7 Qd2+
|
||||
51.Kh1 f5 52.exf6 1-0
|
BIN
Chess/kingb.ico
Before Width: | Height: | Size: 15 KiB |
BIN
Chess/kingb.png
Before Width: | Height: | Size: 2.2 KiB |
BIN
Chess/kingw.png
Before Width: | Height: | Size: 2.6 KiB |
Before Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 2.5 KiB |
Before Width: | Height: | Size: 2.6 KiB |
BIN
Chess/nkingb.png
Before Width: | Height: | Size: 2.6 KiB |
BIN
Chess/nkingw.png
Before Width: | Height: | Size: 2.5 KiB |
Before Width: | Height: | Size: 2.6 KiB |
Before Width: | Height: | Size: 2.7 KiB |
BIN
Chess/npawnb.png
Before Width: | Height: | Size: 2.6 KiB |
BIN
Chess/npawnw.png
Before Width: | Height: | Size: 2.6 KiB |
Before Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 2.9 KiB |
BIN
Chess/nrookb.png
Before Width: | Height: | Size: 2.6 KiB |
BIN
Chess/nrookw.png
Before Width: | Height: | Size: 2.7 KiB |
BIN
Chess/pawnb.png
Before Width: | Height: | Size: 797 B |
BIN
Chess/pawnw.png
Before Width: | Height: | Size: 1.3 KiB |
BIN
Chess/queenb.png
Before Width: | Height: | Size: 2.4 KiB |
BIN
Chess/queenw.png
Before Width: | Height: | Size: 2.2 KiB |
|
@ -1,16 +0,0 @@
|
|||
# PySimpleGUI-Chess A Chess Game Playback Program
|
||||
|
||||
![image](https://user-images.githubusercontent.com/46163555/64135781-4c58a600-cdba-11e9-968d-60ddfb4c8952.png)
|
||||
|
||||
|
||||
## Introduction
|
||||
This is the start of a front-end GUI for an AI engine that plays chess. It simply reads moves the a PGN file and steps through it showing each of the moves on the board.
|
||||
|
||||
To play against the AI run the program
|
||||
Demo_Chess_AGAINST_AI.py
|
||||
|
||||
Locate where the pacakge was installed and run the programs from that folder. You need to run from the installed folder so that the images of the chess pieces are located.
|
||||
|
||||
## Home Page (GitHub)
|
||||
|
||||
[www.PySimpleGUI.com](www.PySimpleGUI.com)
|
|
@ -1,2 +0,0 @@
|
|||
PySimpleGUI==3.9.1
|
||||
python-chess==0.23.9
|
BIN
Chess/rookb.png
Before Width: | Height: | Size: 725 B |
BIN
Chess/rookw.png
Before Width: | Height: | Size: 933 B |
|
@ -1,38 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
import sys
|
||||
if sys.version_info[0] >= 3:
|
||||
import PySimpleGUI as sg
|
||||
else:
|
||||
import PySimpleGUI27 as sg
|
||||
|
||||
import os
|
||||
|
||||
BUTTON_PATH = '.'
|
||||
button_names = ('close', 'cookbook', 'cpu', 'github', 'pysimplegui', 'run', 'storage', 'timer', 'checkmark', 'camera', 'house', 'download')
|
||||
|
||||
|
||||
def ShowMeTheButtons():
|
||||
button_files = [os.path.join(BUTTON_PATH, b+'.png') for b in button_names]
|
||||
|
||||
sg.SetOptions(auto_size_buttons=True, margins=(0,0), button_color=sg.COLOR_SYSTEM_DEFAULT)
|
||||
|
||||
toolbar_buttons = [[sg.RButton('{}'.format(button_names[i]), image_size=(32,32), image_filename=f, pad=(0,0), tooltip=button_names[i]) for i, f in enumerate(button_files)],]
|
||||
|
||||
layout = [[sg.Frame('', toolbar_buttons,)]]
|
||||
|
||||
form = sg.FlexForm('Toolbar',
|
||||
no_titlebar=True,
|
||||
grab_anywhere=True,
|
||||
background_color='grey76',
|
||||
keep_on_top=True,
|
||||
).Layout(layout)
|
||||
|
||||
# ---===--- Loop taking in user input --- #
|
||||
while True:
|
||||
button, value = form.Read()
|
||||
print(button)
|
||||
if button == 'close' or button is None:
|
||||
break # exit button clicked
|
||||
|
||||
if __name__ == '__main__':
|
||||
ShowMeTheButtons()
|
|
@ -1,79 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
import sys
|
||||
if sys.version_info[0] >= 3:
|
||||
import PySimpleGUI as sg
|
||||
else:
|
||||
import PySimpleGUI27 as sg
|
||||
|
||||
import io
|
||||
from PIL import Image
|
||||
import base64
|
||||
import subprocess
|
||||
|
||||
button_names = ('close', 'cookbook', 'cpu', 'github', 'pysimplegui', 'run', 'storage', 'timer')
|
||||
|
||||
|
||||
house64='iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAACXBIWXMAAAsSAAALEgHS3X78AAAHPklEQVRYhbVXbUxb1xl+zjn30/a9/gBsbBwCBhPAUD4W2pClSZM0TemkdZPaSf0RTfszTZv2o1qzqmqiaL82salSqzZptVVqqmRV1dEssERKxJKxLAWajEYkAcxXyoBg4xgcY8AY23c/+EgwNiTRdqTz557zPOd5n/Oe95wLPGFzOp24fPp0yeTJk4cbjxzJelIe9qTA5uPHt7mHho6HOzsP1RQUWODxnO/o6Pj/C3A6naT5/ffLC9raWqZbW2v8t29GEz7/d3dXVuY56us7W69cmX1EHqaqKn1sAWffe6+ipK/vROjChaq+WNj/r2wWN44FEvAHamtcLhtfW3uuo7NT24xHVVUKPIYDzrw80vzuu1WuixdbQufPV3SJC747VcxUWC1ZvtFoRPX6tMX+wR27PJ6CLbt3d3zV1WWy2+0HZVn2APAkEgmPKIqeeDzeAwDhcFgLh8MaeVQB//j445qSrq4TU2fO1HlF+L07BGN5hVmXnWXG4PA4+q/OTVb1RwSjwSRZGxqaLm3deq7z+vU/B4NBjIyMwOfzQVEU+Hw+AgD19fUCAGwqwJmXR08dO1brampqjly7Zuu26/3j35GNNdutOqvVAV4QEA6H0D8wgr7u6OS29oCgSxCj7eWXvyB7snLjCDwLAiSTSe3YB20/avv3aNPD/NxmAk4dPbq9pLX1w3BHh23IrPMH6lW1vMyks+XmQxBEAIDRlI2iIoATJqw9kaS/sDt4P3b27A90d2yJql83EMIzxGILcYGniVT+jAKcDgc99dZbT7tOnGgO9/dn9RZb/f5nzeo2t1lPIGM6GAUlUbBlDxl4WA1GcAcEW2+27LddGiXz7cPqrd9fROXPDkC2GMAYv8q/sgUZBZw6fLi+5PPPj0d6e7NHnNm+qX1Wtdht0muLAj7rVhB0fR81VgLc/AKXTK/ioIuHe/5LFG6NgeMmbTdn4r6szrvM195vIAkN24+8AkYfLNfe3h5bEp4aud3Omo8e3eVubPzrgtdb4PU4fYHvbVFLn3LobblOxKJJdMyWwPXiL/F8XQV6brQjWv8r1D9VBvdsJ7Jy9JBlCXorMYyJmsBGZjA74ENo0IeEq7T5Srf3FrBBHWh5++09ZZ9+eiI2MpL/baHdH/yhS813Z+lzrHmQJD1mQrNIjvXBEf4G/NAFZEXvYCfrRtn9v0MI3oZozYUo6cDxFIZsEWOLiLDAQnR+2Cd7bPkm8759Z77u6oqtqwNOu51refPNvaWNjWcWx8edAzUu3/QrJWphuV2fk+OEJCsglGFuZhYtoTJ0lh2BuXwvvvrPLD6SfwHOtReFiUEYFApKOciyAlEUoOZJwj2zMq0N309GbvWU1VosTxcfOPB1y+XLgXA4rK0K+Nsbbzxfefr0B/GJCceoy+EPveZRHEUWgyXLAUlWQAkDIQxzMzO4Iz+Dssrt2FkkYnzgNsxFz+ClIh7ucBsgLM2jlFtyggKKhTP4CD+FiYg26x1wlypKhfm555qv3bgRZc7cXP7c668frHznnb/EJybsQ3Vuf/hQteIssRnMFgcknRGEstWemI0gSXR4oWARXHQEJVNXUesQ4Ex8C8PkNSQU0+pcSjmIsgJe4GByykooxzgd9wYQ6ekrrTEa64v377/OXqiutv387t0/LHq928bcW3wzP9mu5BRY9EazDZLOuBr5SudFEYViAPpIP5RwP7IMGrIXvJAjXkDgoEnGNfMp5SCIOhCahDFHNAQ5YSoxGsLcwFDRnoaGEDcej09M7NrVNDo+VBR8tcJcVmzT6/QWyDpT2uPJ61RAp0IDoAFIpowTkHX1lTEeJrMTjPlRup/Y2+ZjI4XDscG7VmszAYAd5eXGaHCi7seH6n7TsK9ip6LawPO6tAI+OfklAvem0o4BwEsv7oHH404zoiESnsS9YAD+hfzjv/vtJ38cDoZ6OQDo6Om5D6D1NY3+lOMFUMaDPlS1Hm6Dff2IT42D0vVjszEgUFedEct4AYwTUOyqvnm1b+AGkFIJCWVLi9Olnq7xjEAQCWiaayyhLXOkxWqgjANlHAh5AF4jgFIGxjhQxoNkiIJjFJLIAWStAgJgUUsuJV8GLGU82EYCVqhWsjddY5RCFrjU9UEIEI1vhNWWEjQ1oHSLEMqBMCG9AEZhkLl1W0AAROPxzFhNA8j6xMkgYGMHjBIPgaWQEWBuESCEpsdq2hrrNxGQ2QGOMQgcA5ey/j99KtR44H/hwOY5oOpEiPxash1kAdMzfEYHNE0D8KhbwLiNTwFPwLO1L+98I0FykS47sB5LNDziFhAsO5DpKFHIAoOQ8pIgBJB4BkJpWqz2OElIM0QBLOWAQeIgpiAJAFlkICSTA4+RhNjAAUYpZJGDlLIFhBBIPIOWoRI+hgNk+T7P8F4lFJIkQxHXk0nCIuYJTYsl0ECWk5DQB8/zTf8LUluScAguUG0mvv73bz6exuOHJKwUwg8/+lNk5et/AVSZbsni/k4yAAAAAElFTkSuQmCC'
|
||||
|
||||
|
||||
timer64='iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAACXBIWXMAAAsSAAALEgHS3X78AAAJDUlEQVRYhbWWe2xT1x3Hv/fht6+feTiJm6TYCUnaLYUmJFmb0pWu0NKmYhtQxoaKCmKjRe1aVRVV/xh/dFPfj0mZNFUr3TSKIHQCOtYVSkehzCEkJORpJ8GJY8eO7Xvt2L7O9bV97/5Iy3iEdK3YT7rS0e/e8/t+zvmee84hcJOj/nu31zQ23LkxFAxaWC5WYC8rHQDgPXnq9Mcsx6Wu/Z66meLVTkfxbbU1O/oHBo8Mjbg/8IyNd9TW1g46nc5ilYJew3Kx/rm5OfFmal6OhoY7y3bt/OWftvx8s2qh9y++8PyD69c9+ti1+Zs2AzRFN1lMRu7SpK+nra3NVFuztH3z5s3y8RMn3ABQbLNFCFl+YGjEfeb/AsAw+mVT/oDIxWLee1pbf1dZWbHDarVuanv44erKysqp9/d+cMloND7lDwQ6ruxH3iwAAKlqp0N8+623msxm049NJhOCwWmc/OzEYw+uWf2Q1WKhrGbTzLWd6O+i1NzcTNlsNoYgCCkYDKZcLpfEMMxgZUXF1nSaf5Cm6dJ0mod7eBjfr7+j57U33txnLytd5qyqGsAnn343gBUrVuieeOKJlqmpqXV1dXXFhYWFhlwuJwUCgdnm5uaJlpbmI2Nu96X+vr4VdbffjlGPG/lcDhqt7o9yPjdV7XRs9YyNH7q2LvFNwi+//HLNpk2bfuL1el/geZ6RJAn5fB6iKCKTySCfz0MQBPA8D5VKFRi42FeaSiaIrCiivKIiqNNq3xgZGSnr6x94xTM2fp0FNwRoaWnB9u3b766pqWkXRbEmGo0q3G43RkaGQRIkjEYTQADpdBoAUFRUBJqmkckIYKNRtN5996sfffTRxe6enlEAg/7ANL+QzoIWNDc3EwcPHnxubGzsRY7jzF1dXfB4faioq8cjv9oNvbUIFEWDJAiQkJDmIvBccCE8OY5cLg/GYMSw27NBq2f+7Q9Mn1u+fLnh6NGPt3V1nXs2Fo+fevvtd54LBoPpG87Ae++9d7/D4TgkCIKho6MDKosNP3j0ZygvL4dBo4KSIiCkEpBlQM0wkGUgm81hOhDASOfn8I8OQxRF0DQ9abPZNhRYrVtEUdyq1Wi06TQf1OmZzY9v3fo5sMA+sGfPnhWNjY3vx+Pxko6DHVh61wO4b8PjsJs0QCaNnEKDQIRDmBeRysmIxpOQaQ1CAR90ahWqljWBYYwI+cbBp1KmSCT8kEatrpFlyTo40I+xMc9cU3OLd9++D88uCNDe3v5SIpH40cmTJwmF2YYf/nQLbEYtYpEIhse9CLGzyGQEMAYjFAoFkpEQ2JkAaJpGYVk5aJqCucgGiHOIBAPguJjB4x5h0nwqYbFYhpY3rHjqr/s+/JvH4xGvWwN79+6tmZiY2MGyLBHkEnhk+zYUqglEQ0F4QiwonRmEnEdBsQ0EAFKSYLulHEkuClKWQJEEKGLe2DJnLYRUEix7ApRCGdux86mWJ5/c6X/l9TfTV2petROGw+GHs9kscb6rC433rUFJUQF4ngcrypgYugiapmAtsgGShBQbQZINg5Ak6HU6lFXcCgoySFlCMsZBp2dQU78Mer0ekiRZ9u/fX9LTc+Eq8asA1q1bZ2hsbLw/l8shFo/DcUczrCYDxi55MdR9DnZHNb449Gec/fgg2MAkKBJgjAbMRkNQ0BQUJOBzD6LPdRpZgUdJaSnKKp24dckSGI1GHDt2bP1CC/6yBaIoWjKZjGVmZgaWIhsMJhNIALqSSlSZi8AYzSi7pQJ/efUluLvPYsuzL0GjVkNJkTCZzaBJAuVLHMhmSqHVaEAC0GjUsBYUQqVSIZFIFC0EQF4BYBRF0Tg7OwtjoQ1UXsR0cBoCn4Reb4BOq4W1sAjbdv8WZmshXvv1Npz/16cosFqh+Mp7vU4LlUKBcGAKQiqBdCIOlVoDmqahUCgW0v8vgCRJVDabpURRBK1UIptOYWygDzMTYxD5JCgCIAnAUlCAXzy9GzZ7Ob74+6HLeZokQBEEhHQKQZ8XoalJcJGZRcWvsoCiqKQkSUmappFJ82AshVh272qks/I1IvMQu1//w3yOIi/nSQKw2+2ovMUOigAokkBg3INMJgNBEBYHUCgUCVEUE2q1GlwwBDGbg0pBgyLkq8RJAlAQgNpguCr/9UNfAUsSgIKmkc/nIctyZlELWJYNC4LQTRAEUskEOL8XBGSwQR/YaR+EVAIUCShJYv5/J3HZ+/k2EGcjCAV8SHBRQMqDT8QxOuoBy7JobW39x6IALpdLDofDnyQSCej1elwavIBIYBKTwwOYGO5HPBKEgpgf1fxIv2qT821IEob6ejA+PIQ4x2JksB9cNAKWZeHz+fKrVq36bFELACAcDh93Op1fplKpuyaHL8K+pAqtq9eCJIAUF8WEZwhLnFVQKJUgya+mHTK4cAhSTkTrPfdCp9OAIoBYNILj//wEvb290tq1a9t37dp13V0AuOYscLlcMJlMPMMwD/B8SpWeZVFRVQutRouJ0WGEAz5YrQXQ63WQ81nQBAE5n0N351nkxQwMBgaMXoesIKD3Qg/OdXbC6/V68/n8bwYGBgLfCAAAarV6dOXKlfLk5OR9qUSCmOPCMJpMkHI53OpwoLi0FHPJWZw8dhjh6QBq6upQXV0NnVaLqYlL0Gk1GOzvx9GjR3D69Om59evX7zxz5sxxv9+/kP71ANPT0/lgMHhh5cqVt/n9/qUcGyWSbBgOhxOFJaXQqFRQ0hQyc2kweh3sdjtIAlAraOg0Gnx5+gucPfslTp06Ja5atar98OHDv+/s7JQXVMciV7L6+npm48aNT3d3d78gy7LeaDSiqqoKlY4qFJeUwlpgBUWSSM7OIjOXBhuNYGhoCL29vQiFQqG2trbnOzo69p8/fz53I41FAQCgoaFBuWfPng0HDhx4OhgMNuh0OhQXF8NgMMBisUCtVoPneYTDYfj9fvh8PixduvQIy7LtsVjsU5fLdcOR/08AX8czzzxDxmKxtmw2uyaXy92RyWQMgiAwkiTJSqVyVqVSxfR6vctkMh159913z3xzxW8J8HU0NTWRAOyJRMKQTCYZgiBko9E4azabY9lsNuRyub5NOQDAfwBU9w9d4+VBlQAAAABJRU5ErkJggg=='
|
||||
|
||||
close64 = 'iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAEQ0lEQVR42r2XW2wbRRSG/1177TgkdkyoS4shaaWogVIKRAXUVn4BgRBEIRBSkSK1lAakPhTxABJSK6BEtAoXCUHEWwWi4oEXUAVvRUASSBuJliAh5QJp6hrspoGQi69r73LO7Npu6kvsBGek0ezOrvf79szsmbG0D2iwAN8DaMQaFA0YHQFaLwCX6TQuHQAuNtjR2PawD05LZeFzKeC7b/txPoLxU8Aj1BVkAf1wqw/uejeU9RsASaqYQGp+Dv8EAvjgdD9OAg9S14gQOPKED1XNWyv7+lT0VArxiVH0fCUEOqjr3JoKcImN/pYW2EOnQyUJTESBJkdpgGkV8Cj/owDDdx59A8Mf92FT+GpR+KSlBrt6ehE6+hL0pLp6AYbvfusE5FontFgUZ989UVAiDU+X0OsvQ0/EVy4g4MeOQ3a6Mn38wKHet3MkrofzZJMsFlzpeRVaeLF8ASPsb8Javy7nDXRVxdA7x7FpIZQXnrlP0yDJMoKvHVpZBKq23Qv3M8/nzQt6PIah93qhRxaLwvPNhbLmgGP7Drg694mHlVqKwcsWEBItD8DVvleM6WrhRQXUwBSsnpthvclDY++BZLdnflS9YxecrZ2QFGVZePDIYcq5yWuGK47k39NIzlCdDkHxNuYXiJzrz/xIrr4BFpdbfAFyTS1CSi1uf7IDrqeeheyoLihxubsD2sI8UuEFaItUKfen5mahRcLZl7nft7xAvjIQs+GFP2cLCmjRCL5p3oDN6nzR56xIYDl4ORJlCwyqDnT7Z5aFL5G4w4vN8dnVCwymatA9daVkeCkSJQv8qDtxcDKYF86AwKEuSDYbvB+doq/DlnMPJ6uvmzfmSJQk0E9D+OLVcEG4f38bwgNnxLmz9Wl4+z6HZLXm3JuYHMfE7i0ri8Ck3Y3Hx4L0lvYl8Et7H0Xk7NJ7Xe1d8H74GX2/2YyZmv8XY3euo4SUXJkAFyvtEbdc+CsDn2r3Ifrrz3nHvW7Pftzy/kmxdhSCly2Qlmj66Xf88dB2qP6LRme+jauuo67rIDyvHMN4i1esmvlK6QIUTrEISbKxDnDlPkk2BK6VIDhXXaddP6Vk0H6A9wSUn0WKFn2lCgiYbDEmFVXJYjWOuU1LcHudgAASSLS0FnD4dV4TksYxNEOqsMDwgAAxELToSFZFfGaiVWzGNV6MWM4Uyc5OE8wQCr2AqwmxIuoJowX3k5CjZSd6vvxhqcBj921Fc2g8C2Mwzf5sax7zNZZjSdkcCg6/EEgacAYzlLZvRk1kW7rm39iELwZHsgLPATN311rqb7trG+65dT2FXTEg4o1NoDinZKOYQ8ICFo4ADwMJpEwBDrnKIU+YMqZQ0pAbC4QwODwCf0Rd/BQ4IATagM46oI+CeiNPPVS40EDF6M/pJ78Ap+n0PL8Cp7sGs9asgQSFDLxBmKJ6STKBVSbcZsa10gKcJHi/Hv0PWqbBbaFH/AEAAAAASUVORK5CYII='
|
||||
|
||||
|
||||
def ExecuteCommandSubprocess(command, *args, wait=False):
|
||||
# try:
|
||||
if sys.platform == 'linux':
|
||||
arg_string = ''
|
||||
for arg in args:
|
||||
arg_string += ' ' + str(arg)
|
||||
sp = subprocess.Popen(['python3' + arg_string, ], shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
else:
|
||||
expanded_args = []
|
||||
for a in args:
|
||||
expanded_args += a
|
||||
sp = subprocess.Popen([command, expanded_args], shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
if wait:
|
||||
out, err = sp.communicate()
|
||||
if out:
|
||||
print(out.decode("utf-8"))
|
||||
if err:
|
||||
print(err.decode("utf-8"))
|
||||
# except: pass
|
||||
|
||||
|
||||
def get_image_bytes(image64):
|
||||
image_file = io.BytesIO(base64.b64decode(image64))
|
||||
img = Image.open(image_file)
|
||||
bio = io.BytesIO()
|
||||
img.save(bio, format='PNG')
|
||||
imgbytes = bio.getvalue()
|
||||
return imgbytes
|
||||
|
||||
def ShowMeTheButtons():
|
||||
|
||||
sg.SetOptions(auto_size_buttons=True, margins=(0,0), button_color=sg.COLOR_SYSTEM_DEFAULT)
|
||||
|
||||
toolbar_buttons = [[sg.RButton('', image_data=get_image_bytes(close64),button_color=('white', 'black'), pad=(0,0), key='_close_'),
|
||||
sg.RButton('', image_data=get_image_bytes(timer64), button_color=('white', 'black'), pad=(0, 0), key='_timer_'),
|
||||
sg.RButton('', image_data=get_image_bytes(house64), button_color=('white', 'black'), pad=(0, 0), key='_house_'),
|
||||
]]
|
||||
|
||||
# layout = toolbar_buttons
|
||||
layout = [[sg.Frame('Launcher', toolbar_buttons,title_color='white', background_color='black')]]
|
||||
|
||||
window = sg.Window('Toolbar', no_titlebar=True, grab_anywhere=True, background_color='black').Layout(layout)
|
||||
|
||||
# ---===--- Loop taking in user input --- #
|
||||
while True:
|
||||
button, value = window.Read()
|
||||
print(button)
|
||||
if button == '_close_' or button is None:
|
||||
break # exit button clicked
|
||||
elif button == '_timer_':
|
||||
pass # add your call to launch a timer program
|
||||
elif button == '_cpu_':
|
||||
pass # add your call to launch a CPU measuring utility
|
||||
if __name__ == '__main__':
|
||||
ShowMeTheButtons()
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
import PySimpleGUI as sg
|
||||
import os
|
||||
|
||||
BUTTON_PATH = 'C:/Python/PycharmProjects/GooeyGUI/ButtonGraphics/Good ones/For toolbar'
|
||||
button_names = ('close', 'cookbook', 'cpu', 'github', 'pysimplegui', 'run', 'storage', 'timer')
|
||||
|
||||
|
||||
def ShowMeTheButtons():
|
||||
button_files = [os.path.join(BUTTON_PATH, b+'.png') for b in button_names]
|
||||
|
||||
sg.SetOptions(auto_size_buttons=True, margins=(0,0), button_color=sg.COLOR_SYSTEM_DEFAULT)
|
||||
|
||||
toolbar_buttons = [[sg.RButton('{}'.format(button_names[i]), image_size=(32,32), image_filename=f, pad=(0,0), tooltip=button_names[i]) for i, f in enumerate(button_files)],]
|
||||
|
||||
layout = [[sg.Frame('', toolbar_buttons)]]
|
||||
|
||||
form = sg.FlexForm('Toolbar', no_titlebar=True).Layout(layout)
|
||||
|
||||
# ---===--- Loop taking in user input --- #
|
||||
while True:
|
||||
button, value = form.Read()
|
||||
print(button)
|
||||
if button == 'close' or button is None:
|
||||
break # exit button clicked
|
||||
|
||||
if __name__ == '__main__':
|
||||
ShowMeTheButtons()
|
Before Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 979 B |
Before Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 535 B |
Before Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 772 B |
Before Width: | Height: | Size: 879 B |
Before Width: | Height: | Size: 2.3 KiB |
|
@ -1,262 +0,0 @@
|
|||
import PySimpleGUI as sg
|
||||
import color_themes
|
||||
|
||||
"""
|
||||
Program that is used to create new themes for use with PySimpleGUI's "Look and Feel" settings.
|
||||
You are presented with a grid of mini-windows that is created for color palettes downloaded from https://colorhunt.co/palettes
|
||||
The file color_themes.py contains a large dictionary of approx 1780 palettes.
|
||||
|
||||
For each palette you are shown 4 candidate themes, 2 "light" and 2 "dark". The window shows 5 palettes so you'll have a
|
||||
total of 20 candidate themes displayed in total.
|
||||
Each candidate theme has a 3 options - The button color (text and background), the text color for Input/Multiline elements,
|
||||
and the name of the theme when you save it. These you choose using the radio buttons and one input field.
|
||||
To "save" one of these candidate themes, check the checkbox to the left of the layout, choose the radio buttons for button
|
||||
& text settings and optionally change the theme name that is shown above the grid of OK buttons. By default the name starts
|
||||
with either "Dark" or "Light" and is followed by the first 2 "tags" that were posted with the palette on the colorhunt site.
|
||||
|
||||
After you've selected the themes you want to save from the window of 20 click any "OK" button in the window or close the
|
||||
window with the "X". You will see the dictionary text in the Debug Window and the values will also be written to a file.
|
||||
You'll then be shown the next group of 20 candidate themes.
|
||||
|
||||
If you want to exit the program entirely, click any "Cancel" button the page. Note - cliicking "Cancel" will not save any
|
||||
theme you have checked with the checkbox. You should only exit from a window you have not selected any themes for saving
|
||||
|
||||
If a Theme is selected for saving, then the values for the LOOK_AND_FEEL dictionary are displayed in a debug window and are
|
||||
also appended to the file new_theme_dict.py. You will need to edit the new_theme_dict.py file to get the syntax correct.
|
||||
A "," or "}" may need to be added in order to make the table be correct.
|
||||
|
||||
If you're using this program it's assumed you know what you're doing and understand the LOOK_AND_FEEL dictionary and can
|
||||
figure out how to get the syntax correct for adding it to the main dictionary of themes.
|
||||
"""
|
||||
|
||||
#----------------- Window to get layout for window ---------#
|
||||
|
||||
CANDIDATES_PER_ROW = 4
|
||||
PALETTES_PER_WINDOW = 5
|
||||
STARTING_PALETTE = 0
|
||||
sg.change_look_and_feel('Dark Blue 3')
|
||||
layout = [
|
||||
[sg.T('Choose your window layout (default is a huge window)')],
|
||||
[sg.In(default_text=CANDIDATES_PER_ROW),sg.T('Candidates Per Row')],
|
||||
[sg.In(default_text=PALETTES_PER_WINDOW),sg.T('Palettes Per Window (4 candidates for each)')],
|
||||
[sg.In(default_text=0),sg.T(f'Starting palette number of {len(color_themes.themes)} palettes')],
|
||||
[sg.OK()]]
|
||||
window = sg.Window('Choose Theme Layout', layout,default_element_size=(4,1))
|
||||
event, values = window.read()
|
||||
window.close()
|
||||
|
||||
if event is None:
|
||||
sg.popup_no_buttons('Aborting....', no_titlebar=True, auto_close=True, keep_on_top=True)
|
||||
exit()
|
||||
try:
|
||||
CANDIDATES_PER_ROW = int(values[0])
|
||||
PALETTES_PER_WINDOW = int(values[1])
|
||||
STARTING_PALETTE = int(values[2])
|
||||
except:
|
||||
sg.popup_no_buttons('Bad input... Aborting....', no_titlebar=True, auto_close=True, keep_on_top=True)
|
||||
exit()
|
||||
|
||||
TOTAL_CANDIDATES_PER_PAGE = PALETTES_PER_WINDOW * 4
|
||||
#-----------------------------------------------------------#
|
||||
|
||||
def rgb_to_hsl(r, g, b):
|
||||
r = float(r)
|
||||
g = float(g)
|
||||
b = float(b)
|
||||
high = max(r, g, b)
|
||||
low = min(r, g, b)
|
||||
h, s, v = ((high + low) / 2,)*3
|
||||
if high == low:
|
||||
h = s = 0.0
|
||||
else:
|
||||
d = high - low
|
||||
l = (high + low) / 2
|
||||
s = d / (2 - high - low) if l > 0.5 else d / (high + low)
|
||||
h = {
|
||||
r: (g - b) / d + (6 if g < b else 0),
|
||||
g: (b - r) / d + 2,
|
||||
b: (r - g) / d + 4,
|
||||
}[high]
|
||||
h /= 6
|
||||
return h, s, v
|
||||
|
||||
def hex_to_rgb(hex):
|
||||
hex = hex.lstrip('#')
|
||||
hlen = len(hex)
|
||||
return tuple(int(hex[i:i + hlen // 3], 16) for i in range(0, hlen, hlen // 3))
|
||||
|
||||
|
||||
def sorted_tuple(tup, position):
|
||||
tup.sort(key=lambda x: x[position])
|
||||
return tup
|
||||
|
||||
sg.popup_quick_message('Hang on this could me a few moments....', background_color='red', text_color='white', keep_on_top=True)
|
||||
|
||||
sg.LOOK_AND_FEEL_TABLE = {} # Entirely replace the look and feel table in PySimpleGUI
|
||||
palette_counter = 0
|
||||
for key, colors in color_themes.themes.items():
|
||||
if palette_counter < STARTING_PALETTE:
|
||||
palette_counter += 1
|
||||
continue
|
||||
# Sort the colors from darkest to lightest
|
||||
color_lightness_pairs = []
|
||||
for color in colors:
|
||||
if type(color) in (tuple, list):
|
||||
continue
|
||||
r,g,b = hex_to_rgb(color)
|
||||
lightness = (rgb_to_hsl(r=r, g=g, b=b))[2]
|
||||
color_lightness_pairs.append((lightness, color))
|
||||
sorted_colors_tuples = sorted_tuple(color_lightness_pairs, 0) # sort the pairs by the first item (lightness)
|
||||
scolors = [c for l, c in sorted_colors_tuples] # Colors sorted from darkest to lightest
|
||||
# Create a "Dark" and a "Light" theme based on the sorted colors
|
||||
sg.LOOK_AND_FEEL_TABLE['Dark'+key] = {'BACKGROUND': scolors[0],
|
||||
'TEXT': scolors[3],
|
||||
'INPUT': scolors[2],
|
||||
'TEXT_INPUT': '#000000',
|
||||
'SCROLL': scolors[2],
|
||||
'BUTTON': ('#FFFFFF', scolors[1]),
|
||||
'PROGRESS': sg.DEFAULT_PROGRESS_BAR_COLOR,
|
||||
'BORDER': 1,
|
||||
'SLIDER_DEPTH': 0,
|
||||
'PROGRESS_DEPTH': 0,
|
||||
'COLOR_LIST':scolors,
|
||||
'DESCRIPTION':colors[4]}
|
||||
|
||||
sg.LOOK_AND_FEEL_TABLE['Light'+key] = {'BACKGROUND': scolors[3],
|
||||
'TEXT': scolors[0],
|
||||
'INPUT': scolors[1],
|
||||
'TEXT_INPUT': '#FFFFFF',
|
||||
'SCROLL': scolors[0],
|
||||
'BUTTON': ('#FFFFFF', scolors[2]),
|
||||
'PROGRESS': sg.DEFAULT_PROGRESS_BAR_COLOR,
|
||||
'BORDER': 1,
|
||||
'SLIDER_DEPTH': 0,
|
||||
'PROGRESS_DEPTH': 0,
|
||||
'COLOR_LIST': scolors,
|
||||
'DESCRIPTION':colors[4]}
|
||||
|
||||
sg.LOOK_AND_FEEL_TABLE['Dark2'+key] = {'BACKGROUND': scolors[1],
|
||||
'TEXT': scolors[3],
|
||||
'INPUT': scolors[2],
|
||||
'TEXT_INPUT': '#000000',
|
||||
'SCROLL': scolors[2],
|
||||
'BUTTON': ('#FFFFFF', scolors[1]),
|
||||
'PROGRESS': sg.DEFAULT_PROGRESS_BAR_COLOR,
|
||||
'BORDER': 1,
|
||||
'SLIDER_DEPTH': 0,
|
||||
'PROGRESS_DEPTH': 0,
|
||||
'COLOR_LIST':scolors,
|
||||
'DESCRIPTION':colors[4]}
|
||||
|
||||
|
||||
sg.LOOK_AND_FEEL_TABLE['Light2'+key] = {'BACKGROUND': scolors[2],
|
||||
'TEXT': scolors[0],
|
||||
'INPUT': scolors[1],
|
||||
'TEXT_INPUT': '#FFFFFF',
|
||||
'SCROLL': scolors[0],
|
||||
'BUTTON': ('#FFFFFF', scolors[2]),
|
||||
'PROGRESS': sg.DEFAULT_PROGRESS_BAR_COLOR,
|
||||
'BORDER': 1,
|
||||
'SLIDER_DEPTH': 0,
|
||||
'PROGRESS_DEPTH': 0,
|
||||
'COLOR_LIST': scolors,
|
||||
'DESCRIPTION':colors[4]}
|
||||
|
||||
|
||||
WINDOW_BACKGROUND = 'lightblue'
|
||||
|
||||
def sample_layout(theme_name, colors, description):
|
||||
name = 'Dark' if theme_name.startswith('D') else 'Light'
|
||||
name += "".join(description[:2])
|
||||
layout = [[sg.Text('Text element', size=(12,1)), sg.InputText(' '.join(colors),text_color='#000000' ),sg.Radio('',theme+'1', key='-INPUT_RAD0-'+theme, default=True, metadata='#000000'),
|
||||
sg.Slider((0,10),size=(10,20), orientation='h')],
|
||||
[sg.T(size=(12,1)), sg.InputText(colors[0], text_color='#FFFFFF'),sg.Radio('',theme+'1', key='-INPUT_RAD1-'+theme, metadata='#FFFFFF')],
|
||||
[sg.T(size=(12,1)), sg.InputText(colors[0], text_color=colors[0]),sg.Radio('',theme+'1', key='-INPUT_RAD2-'+theme, metadata=colors[0])],
|
||||
[sg.T(size=(12,1)),sg.InputText(colors[3], text_color=colors[3]),sg.Radio('',theme+'1', key='-INPUT_RAD3-'+theme, metadata=colors[3])],
|
||||
[sg.T(', '.join(description)), sg.In(name, key='-NEW_THEME_NAME-'+theme)],
|
||||
[sg.Button('OK'), sg.Radio('',theme+'2',key='-BTN_RAD1-'+theme, default=True, metadata=sg.DEFAULT_BUTTON_COLOR),
|
||||
sg.Button('OK', button_color=('white', colors[0])),sg.Radio('',theme+'2',key='-BTN_RAD2-'+theme, metadata=('white', colors[0])),
|
||||
sg.Button('OK', button_color=('black', colors[0])),sg.Radio('',theme+'2',key='-BTN_RAD9-'+theme, metadata=('black', colors[0])),
|
||||
sg.Button('OK', button_color=('white', colors[3])),sg.Radio('', theme+'2', key='-BTN_RAD10-' + theme, metadata=('white', colors[3])),
|
||||
sg.Button('OK', button_color=('black', colors[3])),sg.Radio('', theme+'2', key='-BTN_RAD11-' + theme, metadata=('black', colors[3]))],
|
||||
[sg.Button('OK', button_color=(colors[0],colors[1])),sg.Radio('',theme+'2',key='-BTN_RAD3-'+theme, metadata=(colors[0], colors[1])),
|
||||
sg.Button('OK', button_color=(colors[2],colors[1])),sg.Radio('',theme+'2',key='-BTN_RAD4-'+theme, metadata=(colors[2], colors[1])),
|
||||
sg.Button('OK', button_color=(colors[3],colors[1])),sg.Radio('',theme+'2',key='-BTN_RAD5-'+theme, metadata=(colors[3], colors[1])),
|
||||
sg.Button('OK', button_color=(colors[3],colors[0])),sg.Radio('',theme+'2',key='-BTN_RAD7-'+theme, metadata=(colors[3], colors[0])),
|
||||
sg.Button('OK', button_color=(colors[0],colors[3])),sg.Radio('',theme+'2',key='-BTN_RAD8-'+theme, metadata=(colors[0], colors[3])),
|
||||
sg.Button('Cancel', button_color=(colors[3], colors[2])),sg.Radio('',theme+'2',key='-BTN_RAD6-'+theme, metadata=(colors[3], colors[2])),
|
||||
] ]
|
||||
return layout
|
||||
# layout = [[sg.Text('Here is list of some themes', font='Default 18', background_color=WINDOW_BACKGROUND)]]
|
||||
layout = []
|
||||
row = []
|
||||
layouts = []
|
||||
for count, theme in enumerate(sg.LOOK_AND_FEEL_TABLE.keys()):
|
||||
sg.change_look_and_feel(theme)
|
||||
if count and not(count % CANDIDATES_PER_ROW):
|
||||
layout += [row]
|
||||
row = []
|
||||
row += [sg.CB('',text_color='black', background_color=WINDOW_BACKGROUND, key='-CB-'+theme)]
|
||||
row += [sg.Frame(theme, sample_layout(theme, sg.LOOK_AND_FEEL_TABLE[theme]['COLOR_LIST'], sg.LOOK_AND_FEEL_TABLE[theme]['DESCRIPTION']))]
|
||||
if count and not (count % TOTAL_CANDIDATES_PER_PAGE):
|
||||
if layout:
|
||||
layouts.append(layout)
|
||||
layout = []
|
||||
if row:
|
||||
layout += [row]
|
||||
if layout:
|
||||
layouts.append(layout)
|
||||
|
||||
for layout in layouts:
|
||||
window = sg.Window('PySimpleGUI Theme Maker', layout, background_color=WINDOW_BACKGROUND, default_element_size=(30,1))
|
||||
event, values = window.read()
|
||||
if event is not None and event.startswith('Cancel'):
|
||||
break
|
||||
for key, value in values.items():
|
||||
if type(key) is str and key.startswith('-CB-') and value:
|
||||
theme = key[4:]
|
||||
theme_entry = sg.LOOK_AND_FEEL_TABLE[theme]
|
||||
if values['-INPUT_RAD1-'+theme]:
|
||||
input_text_color = window['-INPUT_RAD1-'+theme].metadata
|
||||
elif values['-INPUT_RAD2-'+theme]:
|
||||
input_text_color = window['-INPUT_RAD2-'+theme].metadata
|
||||
elif values['-INPUT_RAD3-'+theme]:
|
||||
input_text_color = window['-INPUT_RAD3-'+theme].metadata
|
||||
elif values['-INPUT_RAD0-'+theme]:
|
||||
input_text_color = window['-INPUT_RAD0-'+theme].metadata
|
||||
else:
|
||||
print('** ERROR none of the radio buttons are true for input text **')
|
||||
continue
|
||||
|
||||
if values['-BTN_RAD1-'+theme]:
|
||||
b_color = window['-BTN_RAD1-'+theme].metadata
|
||||
elif values['-BTN_RAD2-'+theme]:
|
||||
b_color = window['-BTN_RAD2-'+theme].metadata
|
||||
elif values['-BTN_RAD3-'+theme]:
|
||||
b_color = window['-BTN_RAD3-'+theme].metadata
|
||||
elif values['-BTN_RAD4-'+theme]:
|
||||
b_color = window['-BTN_RAD4-'+theme].metadata
|
||||
elif values['-BTN_RAD5-'+theme]:
|
||||
b_color = window['-BTN_RAD5-'+theme].metadata
|
||||
elif values['-BTN_RAD6-'+theme]:
|
||||
b_color = window['-BTN_RAD6-'+theme].metadata
|
||||
elif values['-BTN_RAD7-'+theme]:
|
||||
b_color = window['-BTN_RAD7-'+theme].metadata
|
||||
elif values['-BTN_RAD8-'+theme]:
|
||||
b_color = window['-BTN_RAD8-'+theme].metadata
|
||||
elif values['-BTN_RAD9-'+theme]:
|
||||
b_color = window['-BTN_RAD9-'+theme].metadata
|
||||
elif values['-BTN_RAD10-'+theme]:
|
||||
b_color = window['-BTN_RAD10-'+theme].metadata
|
||||
elif values['-BTN_RAD11-'+theme]:
|
||||
b_color = window['-BTN_RAD11-'+theme].metadata
|
||||
else:
|
||||
print('** ERROR none of the radio buttons are true for button color **')
|
||||
continue
|
||||
sg.LOOK_AND_FEEL_TABLE[theme]['TEXT_INPUT'] = input_text_color
|
||||
sg.LOOK_AND_FEEL_TABLE[theme]['BUTTON'] = b_color
|
||||
with open('new_theme_dict.py', 'a') as outfile:
|
||||
outfile.write(f"'{values['-NEW_THEME_NAME-'+theme]}' : {sg.LOOK_AND_FEEL_TABLE[theme]},\n")
|
||||
sg.Print(f"'{values['-NEW_THEME_NAME-'+theme]}' : {sg.LOOK_AND_FEEL_TABLE[theme]}\n")
|
||||
window.close()
|
||||
del window
|
|
@ -1,172 +0,0 @@
|
|||
# Theme Maker
|
||||
|
||||
## A Tool To Make PySimpleGUI "Look and Feel" Entries
|
||||
|
||||
The Look and Feel themes are defined using a dictionary. Each theme has a dictionary of colors and other settings such as the color for the text, background, input fields, buttons, etc. Generating these themes has been a tedious and long process in the past. This tool was created to make that process easier, more enjoyable, and perhaps something users could participate in.
|
||||
|
||||
This program uses over 1,700 color palettes that were downloaded from https://colorhunt.co/palettes and put into a python file as a dictionary. You'll find the dictionary in `color_themes.py`.
|
||||
|
||||
Here is how the dictionary looks when shortened to 3 entires:
|
||||
|
||||
```python
|
||||
themes = {
|
||||
'163372': ('#f4efd3', '#cccccc', '#c2b0c9', '#9656a1', ['Yellow', 'Grey', 'Purple', 'Pastel']),
|
||||
'163318': ('#594a4e', '#e78fb3', '#ffc0ad', '#6fc1a5', ['Brown', 'Pink', 'Green', 'Vintage']),
|
||||
'163537': ('#ff8ba7', '#ffc6c7', '#faeee7', '#c3f0ca', ['Pink', 'Green', 'Bright', 'Summer']) }
|
||||
```
|
||||
|
||||
## What It Does
|
||||
|
||||
Each palette, a group of 4 colors, is used to present a small "candidate theme layout". A single "candidate" looks like this:
|
||||
|
||||
![SNAG-0587](https://user-images.githubusercontent.com/46163555/69909821-c820b980-13ce-11ea-95fb-03460e7d3873.jpg)
|
||||
|
||||
For each palette you will be presented with 4 of those layouts. Two are "Dark" and two are "Light". You can choose options in each of these layouts and choose to save it.
|
||||
|
||||
The program generates text in a debug window and also appends the text to an output file. This text can be used directly in a look and feel table.
|
||||
|
||||
|
||||
## Installing
|
||||
|
||||
There is no installation if you already have PySimpleGUI installed. Simply download the 2 .py files in this folder and run the one named Theme_Maker.py
|
||||
|
||||
## Running - Initial Window
|
||||
|
||||
The first window you're presented with collects information from you regarding how you would like the theme generation window to be laid out and where to start in the palette dictionary.
|
||||
|
||||
![SNAG-0584](https://user-images.githubusercontent.com/46163555/69909830-0322ed00-13cf-11ea-88da-999d6e901002.jpg)
|
||||
|
||||
|
||||
|
||||
|
||||
![SNAG-0586](https://user-images.githubusercontent.com/46163555/69909820-c820b980-13ce-11ea-94db-0e36af813e25.jpg)
|
||||
|
||||
|
||||
|
||||
|
||||
Program that is used to create new themes for use with PySimpleGUI's "Look and Feel" settings.
|
||||
You are presented with a grid of mini-windows that is created for color palettes downloaded from https://colorhunt.co/palettes
|
||||
The file color_themes.py contains a large dictionary of approx 1780 palettes.
|
||||
|
||||
For each palette you are shown 4 candidate themes, 2 "light" and 2 "dark". The window shows 5 palettes so you'll have a
|
||||
total of 20 candidate themes displayed in total.
|
||||
Each candidate theme has a 3 options - The button color (text and background), the text color for Input/Multiline elements,
|
||||
and the name of the theme when you save it. These you choose using the radio buttons and one input field.
|
||||
To "save" one of these candidate themes, check the checkbox to the left of the layout, choose the radio buttons for button
|
||||
& text settings and optionally change the theme name that is shown above the grid of OK buttons. By default the name starts
|
||||
with either "Dark" or "Light" and is followed by the first 2 "tags" that were posted with the palette on the colorhunt site.
|
||||
|
||||
After you've selected the themes you want to save from the window of 20 click any "OK" button in the window or close the
|
||||
window with the "X". You will see the dictionary text in the Debug Window and the values will also be written to a file.
|
||||
You'll then be shown the next group of 20 candidate themes.
|
||||
|
||||
If you want to exit the program entirely, click any "Cancel" button the page. Note - cliicking "Cancel" will not save any
|
||||
theme you have checked with the checkbox. You should only exit from a window you have not selected any themes for saving
|
||||
|
||||
If a Theme is selected for saving, then the values for the LOOK_AND_FEEL dictionary are displayed in a debug window and are
|
||||
also appended to the file new_theme_dict.py. You will need to edit the new_theme_dict.py file to get the syntax correct.
|
||||
A "," or "}" may need to be added in order to make the table be correct.
|
||||
|
||||
If you're using this program it's assumed you know what you're doing and understand the LOOK_AND_FEEL dictionary and can
|
||||
figure out how to get the syntax correct for adding it to the main dictionary of themes.
|
||||
|
||||
## Choosing and Saving New Themes
|
||||
|
||||
Let's say you were working with these candidate themes:
|
||||
|
||||
![SNAG-0556](https://user-images.githubusercontent.com/46163555/70284016-94f47680-1790-11ea-9e08-1fe7804eaf1a.jpg)
|
||||
|
||||
|
||||
You like the first 2 themes on the second row, so you
|
||||
|
||||
* Mark the checkbox next to each of those 2 themes
|
||||
* Click the 2 radio buttons indicating choice for input text choice and button color
|
||||
* Enter a name to be used for the theme
|
||||
* Click OK anywhere on the screen
|
||||
|
||||
Here is how my choices appear for those 2 entries:
|
||||
|
||||
![SNAG-0577](https://user-images.githubusercontent.com/46163555/70284014-94f47680-1790-11ea-9373-28f80c8a4d31.jpg)
|
||||
|
||||
The result will be that a debug window will open and display the text for the 2 new theme entries for the look and feel theme dictionary.
|
||||
|
||||
![SNAG-0578](https://user-images.githubusercontent.com/46163555/70284013-94f47680-1790-11ea-8be8-507ed929c867.jpg)
|
||||
|
||||
Similar text will be appended to the end of the file "new_theme_dict.py".
|
||||
|
||||
|
||||
## Integrating the New Themes
|
||||
|
||||
Now that you've got the text for the themes it's time to integrate it into your PySimpleGUI environment. The way you do this is that you add your themes direcvtly to the look and feel dictionary.
|
||||
|
||||
Begin by copying the text from either the .py file or the debug window:
|
||||
|
||||
```python
|
||||
'DarkGreenArmy' : {'BACKGROUND': '#3b503d', 'TEXT': '#f1edb3', 'INPUT': '#c8cf94', 'TEXT_INPUT': '#000000', 'SCROLL': '#c8cf94', 'BUTTON': ('#f1edb3', '#3b503d'), 'PROGRESS': ('#01826B', '#D0D0D0'), 'BORDER': 1, 'SLIDER_DEPTH': 0, 'PROGRESS_DEPTH': 0, 'COLOR_LIST': ['#3b503d', '#4a746e', '#c8cf94', '#f1edb3'], 'DESCRIPTION': ['Green', 'Turquoise', 'Yellow']}
|
||||
|
||||
'LightGreenArmy' : {'BACKGROUND': '#f1edb3', 'TEXT': '#3b503d', 'INPUT': '#4a746e', 'TEXT_INPUT': '#f1edb3', 'SCROLL': '#3b503d', 'BUTTON': ('#f1edb3', '#3b503d'), 'PROGRESS': ('#01826B', '#D0D0D0'), 'BORDER': 1, 'SLIDER_DEPTH': 0, 'PROGRESS_DEPTH': 0, 'COLOR_LIST': ['#3b503d', '#4a746e', '#c8cf94', '#f1edb3'], 'DESCRIPTION': ['Green', 'Turquoise', 'Yellow']}
|
||||
```
|
||||
|
||||
This code is written as if you were going to directly add the code inside the PySimpleGUI.py file itself. Instead you'll be adding them directly from your user code rather than modifying the PySimpleGUI.py file.
|
||||
|
||||
Adding the entries to the table can be accomplished using simple assignment to a new dictionary entry. The look and feel dictionary in PySimpleGUI is named `sg.LOOK_AND_FEEL_TABLE`. Here is a sample user program that adds these 2 new themes to the table and then uses one of them to display a window and another to display a popup.
|
||||
|
||||
|
||||
```python
|
||||
import PySimpleGUI as sg
|
||||
|
||||
sg.LOOK_AND_FEEL_TABLE['DarkGreenArmy'] = {'BACKGROUND': '#3b503d', 'TEXT': '#f1edb3', 'INPUT': '#c8cf94', 'TEXT_INPUT': '#000000', 'SCROLL': '#c8cf94',
|
||||
'BUTTON': ('#f1edb3', '#3b503d'), 'PROGRESS': ('#01826B', '#D0D0D0'), 'BORDER': 1, 'SLIDER_DEPTH': 0, 'PROGRESS_DEPTH': 0,
|
||||
'COLOR_LIST': ['#3b503d', '#4a746e', '#c8cf94', '#f1edb3'], 'DESCRIPTION': ['Green', 'Turquoise', 'Yellow']}
|
||||
|
||||
sg.LOOK_AND_FEEL_TABLE['LightGreenArmy'] = {'BACKGROUND': '#f1edb3', 'TEXT': '#3b503d', 'INPUT': '#4a746e', 'TEXT_INPUT': '#f1edb3', 'SCROLL': '#3b503d',
|
||||
'BUTTON': ('#f1edb3', '#3b503d'), 'PROGRESS': ('#01826B', '#D0D0D0'), 'BORDER': 1, 'SLIDER_DEPTH': 0, 'PROGRESS_DEPTH': 0,
|
||||
'COLOR_LIST': ['#3b503d', '#4a746e', '#c8cf94', '#f1edb3'], 'DESCRIPTION': ['Green', 'Turquoise', 'Yellow']}
|
||||
|
||||
sg.change_look_and_feel('Dark Green Army')
|
||||
|
||||
|
||||
layout = [ [sg.Text('My Window')],
|
||||
[sg.Input(key='-IN-')],
|
||||
[sg.Button('Popup'), sg.Button('Exit')] ]
|
||||
|
||||
window = sg.Window('Window Title', layout)
|
||||
|
||||
while True: # Event Loop
|
||||
event, values = window.read()
|
||||
print(event, values)
|
||||
if event in (None, 'Exit'):
|
||||
break
|
||||
if event == 'Popup':
|
||||
sg.ChangeLookAndFeel('Light Green Army')
|
||||
sg.popup('This popup is using a new "Light Green Army" look and feel theme')
|
||||
window.close()
|
||||
```
|
||||
|
||||
## Displaying the New Themes
|
||||
|
||||
When the above program is executed, you are first prsented with a window that's created using the new "DarkGreenArmy" theme. Notice that you can use the "fuzzy theme matching" to make your code more readable by referencing to the theme as "Dark Green Army" when calling `change_look_and_feel`
|
||||
|
||||
![image](https://user-images.githubusercontent.com/46163555/70284546-59f34280-1792-11ea-9a4a-d3aeeb121381.png)
|
||||
|
||||
Clicking the popup causes the light look and feel theme to be loaded prior to calling `popup` to display a window. This will cause the popup to use the light theme and creates this window:
|
||||
|
||||
![image](https://user-images.githubusercontent.com/46163555/70284679-da19a800-1792-11ea-9701-88989cc93ae2.png)
|
||||
|
||||
## Go Make The World More Colorful!!
|
||||
|
||||
Now that you've created some of your very own Look and Feel themes, go use them to create some nice looking windows! **Anything** is better than a default gray window.
|
||||
|
||||
|
||||
|
||||
# Author
|
||||
|
||||
The PySimpleGUI Organization
|
||||
|
||||
|
||||
|
||||
# License
|
||||
|
||||
Copyright 2019 PySimpleGUI.org
|
||||
|
||||
GNU Lesser General Public License (LGPL 3) +
|
|
@ -1,6 +0,0 @@
|
|||
|
||||
# PySimpleGUI openCV YOLO Deep Learning
|
||||
|
||||
To save room in the PySimpleGUI Repo, this project has been moved to its own repo on GitHub
|
||||
|
||||
You'll now find the project at: https://github.com/PySimpleGUI/PySimpleGUI-YOLO
|
|
@ -1 +0,0 @@
|
|||
name = "pysimplegui-exemaker"
|
|
@ -1,84 +0,0 @@
|
|||
import PySimpleGUI as sg
|
||||
import subprocess
|
||||
import shutil
|
||||
import os
|
||||
import sys
|
||||
'''
|
||||
Make a "Windows os" executable with PyInstaller
|
||||
'''
|
||||
|
||||
def main():
|
||||
sg.theme('LightGreen')
|
||||
|
||||
layout = [[sg.Text('PyInstaller EXE Creator', font='Any 15')],
|
||||
[sg.Text('Source Python File'), sg.Input(key='-sourcefile-', size=(45, 1)),
|
||||
sg.FileBrowse(file_types=(("Python Files", "*.py"),))],
|
||||
[sg.Text('Icon File'), sg.Input(key='-iconfile-', size=(45, 1)),
|
||||
sg.FileBrowse(file_types=(("Icon Files", "*.ico"),))],
|
||||
[sg.Frame('Output', font='Any 15', layout=[
|
||||
[sg.Output(size=(65, 15), font='Courier 10')]])],
|
||||
[sg.Button('Make EXE', bind_return_key=True),
|
||||
sg.Button('Quit', button_color=('white', 'firebrick3')) ],
|
||||
[sg.Text('Made with PySimpleGUI (www.PySimpleGUI.org)', auto_size_text=True, font='Courier 8')]]
|
||||
|
||||
window = sg.Window('PySimpleGUI EXE Maker', layout, auto_size_text=False, auto_size_buttons=False, default_element_size=(20,1), text_justification='right')
|
||||
# ---===--- Loop taking in user input --- #
|
||||
while True:
|
||||
|
||||
event, values = window.read()
|
||||
if event in ('Exit', 'Quit', None):
|
||||
break
|
||||
|
||||
source_file = values['-sourcefile-']
|
||||
icon_file = values['-iconfile-']
|
||||
|
||||
icon_option = '-i "{}"'.format(icon_file) if icon_file else ''
|
||||
source_path, source_filename = os.path.split(source_file)
|
||||
workpath_option = '--workpath "{}"'.format(source_path)
|
||||
dispath_option = '--distpath "{}"'.format(source_path)
|
||||
specpath_option = '--specpath "{}"'.format(source_path)
|
||||
folder_to_remove = os.path.join(source_path, source_filename[:-3])
|
||||
file_to_remove = os.path.join(source_path, source_filename[:-3]+'.spec')
|
||||
command_line = 'pyinstaller -wF --clean "{}" {} {} {} {}'.format(source_file, icon_option, workpath_option, dispath_option, specpath_option)
|
||||
|
||||
if event == 'Make EXE':
|
||||
try:
|
||||
print(command_line)
|
||||
print('Making EXE...the program has NOT locked up...')
|
||||
window.refresh()
|
||||
# print('Running command {}'.format(command_line))
|
||||
out, err = runCommand(command_line, window=window)
|
||||
shutil.rmtree(folder_to_remove)
|
||||
os.remove(file_to_remove)
|
||||
print('**** DONE ****')
|
||||
except:
|
||||
sg.PopupError('Something went wrong', 'close this window and copy command line from text printed out in main window','Here is the output from the run', out)
|
||||
print('Copy and paste this line into the command prompt to manually run PyInstaller:\n\n', command_line)
|
||||
|
||||
|
||||
def runCommand(cmd, timeout=None, window=None):
|
||||
""" run shell command
|
||||
|
||||
@param cmd: command to execute
|
||||
@param timeout: timeout for command execution
|
||||
|
||||
@return: (return code from command, command output)
|
||||
"""
|
||||
|
||||
p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
output = ''
|
||||
for line in p.stdout:
|
||||
line = line.decode(errors='replace' if (sys.version_info) < (3, 5)
|
||||
else 'backslashreplace').rstrip()
|
||||
output += line
|
||||
print(line)
|
||||
if window:
|
||||
window.Refresh()
|
||||
|
||||
retval = p.wait(timeout)
|
||||
|
||||
return (retval, output)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
|
@ -1,25 +0,0 @@
|
|||
# PySimpleGUI-exemaker
|
||||
|
||||
## Introduction
|
||||
This package contains a GUI front-end to PyInstaller. Use this tool to create EXE files from your python programs
|
||||
|
||||
![snag-0086](https://user-images.githubusercontent.com/13696193/46968655-c2103200-d081-11e8-926f-d5f977e726f3.jpg)
|
||||
|
||||
|
||||
## Installing
|
||||
|
||||
When you install PySimpleGUI-exemaker, it will install the other components that it requires. To install, on windows, type this into a command prompt:
|
||||
|
||||
pip install pysimplegui-exemaker
|
||||
|
||||
|
||||
## PySimpleGUI Project
|
||||
|
||||
This program was built as a sample application of the PySimpleGUI GUI Framework.
|
||||
|
||||
|
||||
## Running the program
|
||||
|
||||
After your pip install, type this into your command prompt:
|
||||
|
||||
python -m pysimplegui-exemaker.pysimplegui-exemaker
|
|
@ -1,27 +0,0 @@
|
|||
import setuptools
|
||||
|
||||
with open("README.md", "r") as fh:
|
||||
long_description = fh.read()
|
||||
|
||||
setuptools.setup(
|
||||
name="pysimplegui-exemaker",
|
||||
version="1.0.0",
|
||||
author="PySimpleGUI.org",
|
||||
author_email="info@PySimpleGUI.org",
|
||||
description="A GUI Front-end to PyInstaller",
|
||||
long_description=long_description,
|
||||
long_description_content_type="text/markdown",
|
||||
install_requires=['PyInstaller', 'pysimplegui'],
|
||||
url="https://github.com/MikeTheWatchGuy/PySimpleGUI",
|
||||
packages=setuptools.find_packages(),
|
||||
classifiers=[
|
||||
"Programming Language :: Python :: 2.7",
|
||||
"Programming Language :: Python :: 3",
|
||||
"Programming Language :: Python :: 3.4",
|
||||
"Programming Language :: Python :: 3.5",
|
||||
"Programming Language :: Python :: 3.6",
|
||||
"Programming Language :: Python :: 3.7",
|
||||
"License :: OSI Approved :: MIT License",
|
||||
"Operating System :: Microsoft :: Windows ",
|
||||
],
|
||||
)
|
|
@ -1,6 +0,0 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block content %}
|
||||
<h1 id="404-page-not-found">404</h1>
|
||||
<p><strong>Page not found</strong></p>
|
||||
{% endblock %}
|
|
@ -1,107 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
{%- block site_meta %}
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
{%- if page and page.is_homepage %}
|
||||
<meta name="description" content="{{ config.site_description }}">{% endif %}
|
||||
{%- if config.site_author %}
|
||||
<meta name="author" content="{{ config.site_author }}">{% endif %}
|
||||
{%- if config.site_favicon %}
|
||||
<link rel="shortcut icon" href="{{ config.site_favicon|url }}">
|
||||
{%- else %}
|
||||
<link rel="shortcut icon" href="{{ 'img/favicon.ico'|url }}">{% endif %}
|
||||
{%- endblock %}
|
||||
|
||||
{%- block htmltitle %}
|
||||
<title>{% if page and page.title and not page.is_hompage %}{{ page.title|striptags }} — {% endif %}{{ config.site_name }}</title>
|
||||
{%- endblock %}
|
||||
|
||||
{%- block styles %}
|
||||
<link rel="stylesheet" href="//fonts.googleapis.com/css?family=Lato:400,700">
|
||||
<link rel="stylesheet" href="//cdn.jsdelivr.net/gh/tonsky/FiraCode@1.206/distr/fira_code.css">
|
||||
<link rel="stylesheet" href="//use.fontawesome.com/releases/v5.8.1/css/all.css">
|
||||
<link rel="stylesheet" href="//use.fontawesome.com/releases/v5.8.1/css/v4-shims.css">
|
||||
<link rel="stylesheet" href="{{ 'css/theme.css'|url }}">
|
||||
{%- if config.theme.highlightjs %}
|
||||
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/github.min.css">
|
||||
{%- endif %}
|
||||
{%- for path in config['extra_css'] %}
|
||||
<link rel="stylesheet" href="{{ path|url }}">
|
||||
{%- endfor %}
|
||||
{%- endblock %}
|
||||
|
||||
{%- block libs %}
|
||||
<script src="//code.jquery.com/jquery-2.1.1.min.js"></script>
|
||||
{%- if config.theme.highlightjs %}
|
||||
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js"></script>
|
||||
{%- for lang in config.theme.hljs_languages %}
|
||||
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/languages/{{lang}}.min.js"></script>
|
||||
{%- endfor %}
|
||||
<script>
|
||||
hljs.initHighlightingOnLoad();
|
||||
</script>
|
||||
{%- endif %}
|
||||
{%- endblock %}
|
||||
|
||||
{%- block extrahead %} {% endblock %}
|
||||
</head>
|
||||
|
||||
<body ontouchstart="">
|
||||
<div id="container">
|
||||
<aside>
|
||||
<div class="home">
|
||||
<div class="title">
|
||||
<button class="hamburger"></button>
|
||||
<a href="{{ nav.homepage.url|url }}" class="site-name"> {{ config.site_name }}</a>
|
||||
</div>
|
||||
{%- if config.theme.version -%}
|
||||
<div class="version">{{ config.theme.version }}</div>
|
||||
{%- endif %}
|
||||
{%- if 'search' in config['plugins'] %}
|
||||
<div class="search">
|
||||
{%- block search_button %}
|
||||
{% include "searchbox.html" %}
|
||||
{%- endblock %}
|
||||
</div>
|
||||
{%- endif %}
|
||||
</div>
|
||||
<nav class="nav">
|
||||
{%- block site_nav %}
|
||||
<ul class="root">
|
||||
{%- set navlevel = 1 %}
|
||||
{%- for nav_item in nav %}
|
||||
<li class="toctree-l{{ navlevel }}{% if nav_item.active and not nav_item.children %} current{%endif%}">
|
||||
{%- include 'nav.html' -%}
|
||||
</li>
|
||||
{%- endfor %}
|
||||
</ul>
|
||||
{%- endblock %}
|
||||
</nav>
|
||||
{% include "repo.html" %}
|
||||
</aside>
|
||||
<div id="spacer"><button class="arrow"></button></div>
|
||||
<main>
|
||||
<div class="home-top">
|
||||
<button class="hamburger"></button>
|
||||
<a href="{{ nav.homepage.url|url }}" class="site-name"> {{ config.site_name }}</a>
|
||||
</div>
|
||||
<div id="main">
|
||||
<nav class="breadcrumbs">{% include "breadcrumbs.html" %}</nav>
|
||||
{% block content %}<div id="content">{{ page.content }}</div>{% endblock %}
|
||||
{% block footer %}{% include "footer.html" %}{% endblock %}
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
{%- block scripts %}
|
||||
<script>var base_url = '{{ base_url }}';</script>
|
||||
<script src="{{ 'js/theme.js'|url }}"></script>
|
||||
{%- for path in config['extra_javascript'] %}
|
||||
<script src="{{ path|url }}"></script>{% endfor %}
|
||||
{%- endblock %}
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -1,12 +0,0 @@
|
|||
{% if page %}
|
||||
<ul>
|
||||
{% for doc in page.ancestors|reverse -%}
|
||||
{%- if doc.link -%}
|
||||
<li><a href="{{ doc.link|e }}">{{ doc.title }}</a>
|
||||
{%- else -%}
|
||||
<li>{{ doc.title }}
|
||||
{%- endif -%}
|
||||
{%- if not loop.last %} » {% endif %}</li>
|
||||
{%- endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
|
@ -1,657 +0,0 @@
|
|||
html {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
*, *::before, *::after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body, button {
|
||||
font-family: Lato, "Yu Gothic Medium", "游ゴシック Medium", YuGothic, "游ゴシック体", "ヒラギノ角ゴ Pro W3", "メイリオ", sans-serif;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: "Fira Code", "Courier New", Consolas, monospace;
|
||||
font-size: 0.83rem;
|
||||
color: #7700FF;
|
||||
border: 1px solid #E0E0E0;
|
||||
border-radius: 3px;
|
||||
padding: 1px 4px;
|
||||
margin: 0px 1px;
|
||||
background: white;
|
||||
}
|
||||
|
||||
pre code {
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
|
||||
p {
|
||||
line-height: 1.65rem;
|
||||
}
|
||||
|
||||
main ul {
|
||||
margin-top: 0px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
main li {
|
||||
margin-top: 4px;
|
||||
margin-bottom: 4px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
pre {
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #39f;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
button {
|
||||
font-size: 1rem;
|
||||
cursor: pointer;
|
||||
border: none;
|
||||
background: transparent;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
/* ul, ol, dl {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
list-style-image: none;
|
||||
} */
|
||||
|
||||
.nav ul,
|
||||
.breadcrumbs ul {
|
||||
padding: 0px;
|
||||
list-style-type: none;
|
||||
}
|
||||
|
||||
.site-name {
|
||||
display: inline-block;
|
||||
color: #ddd;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.site-name::before {
|
||||
font-family: "Font Awesome 5 Free";
|
||||
content: "\f015";
|
||||
}
|
||||
|
||||
.nav-item {
|
||||
display: block;
|
||||
position: relative;
|
||||
font-size: 0.95rem;
|
||||
line-height: 1.1;
|
||||
padding-top: 5px;
|
||||
padding-bottom: 5px;
|
||||
padding-right: 5px;
|
||||
}
|
||||
|
||||
.nav-item.section {
|
||||
color: #ddd;
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.nav-item.section:hover {
|
||||
background: #999;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
a.nav-item {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
a.nav-item.current {
|
||||
color: #333;
|
||||
background: #eee;
|
||||
}
|
||||
|
||||
a.nav-item.current:hover {
|
||||
color: #333;
|
||||
background: #bbb;
|
||||
}
|
||||
|
||||
a.nav-item:hover {
|
||||
background: #666;
|
||||
}
|
||||
|
||||
.subnav.hide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.nav-item.section::before {
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
width: 5px;
|
||||
}
|
||||
|
||||
.nav-item.section::before {
|
||||
font-family: "Font Awesome 5 Free";
|
||||
font-weight: bold;
|
||||
content: "\f107";
|
||||
}
|
||||
|
||||
.nav-item.section.hide::before {
|
||||
content: "\f105";
|
||||
}
|
||||
|
||||
.toctree-l1>.nav-item.section {
|
||||
padding-left: 25px;
|
||||
}
|
||||
|
||||
.toctree-l1>a.nav-item {
|
||||
padding-left: 25px;
|
||||
}
|
||||
|
||||
.toctree-l1>.nav-item.section::before {
|
||||
left: 10px;
|
||||
}
|
||||
|
||||
.toctree-l2>.nav-item.section {
|
||||
padding-left: 35px;
|
||||
}
|
||||
|
||||
.toctree-l2>a.nav-item {
|
||||
padding-left: 25px;
|
||||
}
|
||||
|
||||
.toctree-l2>.nav-item.section::before {
|
||||
left: 20px;
|
||||
}
|
||||
|
||||
.toctree-l3>.nav-item.section {
|
||||
padding-left: 45px;
|
||||
}
|
||||
|
||||
.toctree-l3>a.nav-item {
|
||||
padding-left: 35px;
|
||||
}
|
||||
|
||||
.toctree-l3>.nav-item.section::before {
|
||||
left: 30px;
|
||||
}
|
||||
|
||||
.toctree-l4>.nav-item.section {
|
||||
padding-left: 55px;
|
||||
}
|
||||
|
||||
.toctree-l4>a.nav-item {
|
||||
padding-left: 45px;
|
||||
}
|
||||
|
||||
.toctree-l4>.nav-item.section::before {
|
||||
left: 40px;
|
||||
}
|
||||
|
||||
.toctree-l5>.nav-item.section {
|
||||
padding-left: 65px;
|
||||
}
|
||||
|
||||
.toctree-l5>a.nav-item {
|
||||
padding-left: 55px;
|
||||
}
|
||||
|
||||
.toctree-l5>.nav-item.section::before {
|
||||
left: 50px;
|
||||
}
|
||||
|
||||
.toctree-l6>.nav-item.section {
|
||||
padding-left: 75px;
|
||||
}
|
||||
|
||||
.toctree-l6>a.nav-item {
|
||||
padding-left: 65px;
|
||||
}
|
||||
|
||||
.toctree-l6>.nav-item.section::before {
|
||||
left: 45px;
|
||||
}
|
||||
|
||||
.nav-item.toc {
|
||||
background: #ccc;
|
||||
color: #555;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.nav-item.toc:hover {
|
||||
background: #bbb;
|
||||
color: #555;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.repo div {
|
||||
padding: 0 10px;
|
||||
}
|
||||
|
||||
.repo div:first-child {
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.repo a {
|
||||
color: #ddd;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.breadcrumbs li {
|
||||
font-size: 0.9rem;
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.footer-buttons {
|
||||
position: relative;
|
||||
height: 2.5rem;
|
||||
}
|
||||
|
||||
.footer-buttons .previous {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.footer-buttons .next {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.footer-buttons a {
|
||||
display: inline-block;
|
||||
color: #444;
|
||||
background: #eee;
|
||||
padding: 4px 8px;
|
||||
border: 1px solid #ccc;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.footer-buttons span::after,
|
||||
.footer-buttons span::before {
|
||||
font-family: "Font Awesome 5 Free";
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.footer-buttons .previous span::before {
|
||||
margin-right: 6px;
|
||||
content: "\f359";
|
||||
}
|
||||
|
||||
.footer-buttons .next span::after {
|
||||
margin-left: 6px;
|
||||
content: "\f35a";
|
||||
}
|
||||
|
||||
.footer-note {
|
||||
display: flex;
|
||||
font-size: 0.9rem;
|
||||
color: #aaa;
|
||||
height: 40px;
|
||||
border-top: 1px solid #ccc;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.footer-note a {
|
||||
color: #88d;
|
||||
}
|
||||
|
||||
/**************************************/
|
||||
/* layout */
|
||||
/**************************************/
|
||||
#container {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
aside {
|
||||
flex: 0 0 300px;
|
||||
width: 300px;
|
||||
order: 1;
|
||||
background: #333;
|
||||
z-index: 999;
|
||||
}
|
||||
|
||||
aside>* {
|
||||
width: inherit;
|
||||
}
|
||||
|
||||
.home, .home-top {
|
||||
display: flex;
|
||||
background: #48c;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.home {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.home .search input {
|
||||
display: inline-block;
|
||||
border-radius: 40px;
|
||||
padding: 4px 10px;
|
||||
outline: none;
|
||||
width: 250px;
|
||||
border: 1px solid #999;
|
||||
}
|
||||
|
||||
.nav {
|
||||
position: fixed;
|
||||
overflow-y: auto;
|
||||
background: #333;
|
||||
}
|
||||
|
||||
.repo {
|
||||
display: flex;
|
||||
background: #222;
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
height: 40px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
#spacer {
|
||||
flex: 0 0 22px;
|
||||
order: 2;
|
||||
}
|
||||
|
||||
main {
|
||||
flex: 1 1 300px;
|
||||
order: 3;
|
||||
min-width: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 768px) {
|
||||
html.show {
|
||||
overflow-y: hidden;
|
||||
}
|
||||
|
||||
aside {
|
||||
display: none;
|
||||
}
|
||||
|
||||
aside.show {
|
||||
display: block;
|
||||
flex: 0 0 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.home, .home-top {
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.home-top {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.home .version,
|
||||
.home .search {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.hamburger {
|
||||
position: absolute;
|
||||
right: 15px;
|
||||
}
|
||||
|
||||
.hamburger::before {
|
||||
font-family: "Font Awesome 5 Free";
|
||||
content: "\f0c9";
|
||||
font-weight: bold;
|
||||
color: #ddd;
|
||||
font-size: 1.3rem;
|
||||
}
|
||||
|
||||
.nav {
|
||||
top: 40px;
|
||||
height: calc(100% - 80px);
|
||||
}
|
||||
|
||||
.site-name.hide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#spacer {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#main {
|
||||
margin: 10px 15px;
|
||||
}
|
||||
|
||||
.footer-note {
|
||||
display: none;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 1.45rem;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 1.3rem;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: 1.15rem;
|
||||
}
|
||||
|
||||
h5 {
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
h6 {
|
||||
font-size: 1.0rem;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (min-width: 768px) {
|
||||
.home-top {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.home {
|
||||
height: 100px;
|
||||
}
|
||||
|
||||
.home .title {
|
||||
margin-top: 5px;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
|
||||
.home .version {
|
||||
margin-bottom: 2px;
|
||||
color: #aaa;
|
||||
}
|
||||
|
||||
.nav {
|
||||
top: 100px;
|
||||
height: calc(100% - 140px);
|
||||
}
|
||||
|
||||
#main {
|
||||
margin: 10px 50px 10px 30px;
|
||||
}
|
||||
|
||||
.hamburger {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.arrow {
|
||||
position: fixed;
|
||||
top: calc(50% - 23px);
|
||||
bottom: calc(50% - 23px);
|
||||
border: 1px solid #eee;
|
||||
border-radius: 0px 14px 14px 0px;
|
||||
padding-left: 3px;
|
||||
padding-right: 6px;
|
||||
margin-left: -10px;
|
||||
transition: 0.3s ease 0s;
|
||||
}
|
||||
|
||||
.arrow::before {
|
||||
font-family: "Font Awesome 5 Free";
|
||||
content: "\f053";
|
||||
font-weight: bold;
|
||||
color: #fff;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.arrow.hide::before {
|
||||
content: "\f054";
|
||||
}
|
||||
|
||||
.arrow:hover {
|
||||
background: #555;
|
||||
color: #ddd;
|
||||
border-color: #555;
|
||||
margin-left: 0px;
|
||||
}
|
||||
|
||||
aside.hide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 1.65rem;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
|
||||
h5 {
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
h6 {
|
||||
font-size: 1.0rem;
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************
|
||||
Table style
|
||||
**************************************************/
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
font-size: 0.9rem;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
th, td {
|
||||
text-align: center;
|
||||
padding: 2px 4px;
|
||||
}
|
||||
|
||||
th {
|
||||
color: darkblue;
|
||||
background: #eee;
|
||||
border: 1px solid #333;
|
||||
}
|
||||
|
||||
td {
|
||||
color: black;
|
||||
border: 1px solid #b9b9b9;
|
||||
}
|
||||
|
||||
tr th:first-child, tr td:first-child {
|
||||
border-left: 1px solid #333366;
|
||||
}
|
||||
|
||||
tr th:last-child, tr td:last-child {
|
||||
border-right: 1px solid #333366;
|
||||
}
|
||||
|
||||
tr:first-child td, tr:first-child th {
|
||||
border-top: 1px solid #333366;
|
||||
}
|
||||
|
||||
tr:last-child td, tr:last-child th {
|
||||
border-bottom: 1px solid #333366;
|
||||
}
|
||||
|
||||
tbody tr:nth-child(2n+1) td {
|
||||
background: #fafafa;
|
||||
}
|
||||
|
||||
.admonition {
|
||||
margin-top: 20px;
|
||||
margin-bottom: 20px;
|
||||
padding: 0px;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
.admonition.note {
|
||||
background: #F0F0FF;
|
||||
}
|
||||
|
||||
.note p.admonition-title {
|
||||
color: white;
|
||||
background: #555599;
|
||||
margin: 0px;
|
||||
padding: 4px 8px;
|
||||
}
|
||||
|
||||
.note p.admonition-title:before {
|
||||
font-family: "Font Awesome 5 Free";
|
||||
content: "\f303";
|
||||
font-weight: 900;
|
||||
padding-right: 5px;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.admonition.warning {
|
||||
background: #FFEEEE;
|
||||
}
|
||||
|
||||
.warning p.admonition-title {
|
||||
color: white;
|
||||
background: #FF6666;
|
||||
margin: 0px;
|
||||
padding: 4px 8px;
|
||||
}
|
||||
|
||||
.warning p.admonition-title:before {
|
||||
font-family: "Font Awesome 5 Free";
|
||||
content: "\f071";
|
||||
font-weight: 900;
|
||||
padding-right: 5px;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.admonition p {
|
||||
margin-top: 5px;
|
||||
margin-left: 10px;
|
||||
margin-bottom: 5px;
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
.admonition pre {
|
||||
margin-top: 5px;
|
||||
margin-left: 15px;
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
<footer>
|
||||
{%- block next_prev %}
|
||||
{%- if page and page.next_page or page.previous_page %}
|
||||
<div class="footer-buttons">
|
||||
{%- if page.previous_page %}
|
||||
<div class="previous"><a href="{{ page.previous_page.url|url }}" title="{{ page.previous_page.title|striptags }}"><span>Previous</span></a></div>
|
||||
{%- endif %}
|
||||
{%- if page.next_page %}
|
||||
<div class="next"><a href="{{ page.next_page.url|url }}" title="{{ page.next_page.title|striptags }}"><span>Next</span></a></div>
|
||||
{%- endif %}
|
||||
</div>
|
||||
{%- endif %}
|
||||
{%- endblock %}
|
||||
<div class="footer-note">
|
||||
<p>
|
||||
Built with <a href="http://www.mkdocs.org">MkDocs</a> using
|
||||
<a href="https://github.com/daizutabi/mkdocs-ivory">Ivory theme</a>.
|
||||
</p>
|
||||
</div>
|
||||
</footer>
|
Before Width: | Height: | Size: 1.1 KiB |
|
@ -1,21 +0,0 @@
|
|||
function ready() {
|
||||
$('.nav .section').each(function() {
|
||||
$(this).click(function(e) {
|
||||
$(this).toggleClass("hide");
|
||||
$(this).parent().children(".subnav").toggleClass("hide");
|
||||
});
|
||||
});
|
||||
|
||||
$('.hamburger').click(function(e) {
|
||||
$('html').toggleClass("show");
|
||||
$('aside').toggleClass("show");
|
||||
$('.home-top .site-name').toggleClass("hide");
|
||||
});
|
||||
|
||||
$('.arrow').click(function(e) {
|
||||
$('aside').toggleClass("hide");
|
||||
$(this).toggleClass("hide");
|
||||
});
|
||||
}
|
||||
|
||||
$(ready);
|
|
@ -1,10 +0,0 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{#
|
||||
The entry point for the ReadTheDocs Theme.
|
||||
|
||||
Any theme customisations should override this file to redefine blocks defined in
|
||||
the various templates. The custom theme should only need to define a main.html
|
||||
which `{% extends "base.html" %}` and defines various blocks which will replace
|
||||
the blocks defined in base.html and its included child templates.
|
||||
#}
|
|
@ -1,10 +0,0 @@
|
|||
# Config options for 'ivory' theme
|
||||
|
||||
static_templates:
|
||||
- 404.html
|
||||
|
||||
include_search_page: true
|
||||
search_index_only: false
|
||||
|
||||
highlightjs: true
|
||||
hljs_languages: []
|
|
@ -1,22 +0,0 @@
|
|||
{%- if nav_item.is_section -%}
|
||||
<button class="section nav-item{% if navlevel > 1 and not nav_item.active %} hide{% endif %}">{{ nav_item.title }}</button>
|
||||
{%- elif nav_item.toc -%}
|
||||
{%- for toc_item in nav_item.toc -%}
|
||||
<a class="nav-item{% if nav_item.active %} current{%endif%}" href="{{ nav_item.url|url }}">{{ nav_item.title }}</a>
|
||||
{%- endfor %}
|
||||
{%- else %}
|
||||
<a class="nav-item{% if nav_item.active %} current{%endif%}" href="{{ nav_item.url|url }}">{{ nav_item.title }}</a>
|
||||
{%- endif -%}
|
||||
|
||||
{%- if nav_item == page or nav_item.children %}
|
||||
<ul class="subnav{% if navlevel > 1 and not nav_item.active %} hide{% endif %}">
|
||||
{%- if nav_item == page %}{% include 'toc.html' %}{%- endif %}
|
||||
{%- if nav_item.children %}
|
||||
{%- set navlevel = navlevel + 1 %}
|
||||
{%- for nav_item in nav_item.children %}
|
||||
<li class="toctree-l{{ navlevel }}{% if nav_item.active %} current{%endif%}">{% include 'nav.html' %}</li>
|
||||
{%- endfor %}
|
||||
{%- set navlevel = navlevel - 1%}
|
||||
{%- endif %}
|
||||
</ul>
|
||||
{%- endif %}
|
|
@ -1,19 +0,0 @@
|
|||
<div class="repo">
|
||||
{%- if config.repo_name %}
|
||||
<div class="link">
|
||||
{%- if config.repo_name == 'GitHub' %}
|
||||
<a href="{{ config.repo_url }}" class="fa fa-github"> GitHub</a>
|
||||
{%- elif config.repo_name == 'Bitbucket' %}
|
||||
<a href="{{ config.repo_url }}" class="icon icon-bitbucket"> BitBucket</a>
|
||||
{%- elif config.repo_name == 'GitLab' %}
|
||||
<a href="{{ config.repo_url }}" class="icon icon-gitlab"> GitLab</a>
|
||||
{%- endif %}
|
||||
</div>
|
||||
{%- endif %}
|
||||
{%- if page.previous_page %}
|
||||
<div class="previous"><a href="{{ page.previous_page.url|url }}">« Previous</a></div>
|
||||
{%- endif %}
|
||||
{%- if page.next_page %}
|
||||
<div class="next"><a href="{{ page.next_page.url|url }}">Next »</a></div>
|
||||
{%- endif %}
|
||||
</div>
|
|
@ -1,16 +0,0 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<h1 id="search">Search Results</h1>
|
||||
|
||||
<form id="content_search" action="search.html">
|
||||
<span role="status" aria-live="polite" class="ui-helper-hidden-accessible"></span>
|
||||
<input name="q" id="mkdocs-search-query" type="text" class="search_input search-query ui-autocomplete-input" placeholder="Search the Docs" autocomplete="off" autofocus title="Type search term here">
|
||||
</form>
|
||||
|
||||
<div id="mkdocs-search-results" class="search-results">
|
||||
Searching...
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
|
@ -1,5 +0,0 @@
|
|||
<div role="search">
|
||||
<form id="rtd-search-form" class="wy-form" action="{{ base_url }}/search.html" method="get">
|
||||
<input type="text" name="q" placeholder="Search docs" title="Type search term here" />
|
||||
</form>
|
||||
</div>
|
|
@ -1,7 +0,0 @@
|
|||
{%- for toc_item in page.toc %}
|
||||
{%- if toc_item.children %}
|
||||
{%- for toc_item in toc_item.children %}
|
||||
<li class="toctree-l{{ navlevel + 1 }}"><a class="nav-item toc" href="{{ toc_item.url }}">{{ toc_item.title }}</a></li>
|
||||
{%- endfor %}
|
||||
{%- endif %}
|
||||
{%- endfor %}
|