2014-01-09 155 views
0

問題是我輸入彈出不得不如此改變tk.Tk()來tk.Toplevel()使得它很好地工作一個頂層窗口;)的Tkinter不能分配文本變量

#Josh Harrison 
#3008088 

from graphics import * 
from random import randrange 

import winsound, sys 

#scale for size of squares 
scale = 50 

#setupBoard sets up the board with a randomly generated puzzle 
def setupBoard(size, color): 
    board = [[[0, Rectangle(Point(scale*.05,scale*.05),Point(scale*.95,scale*.95))] for x in range(size)] for x in range(size)] 
    for x in range(size): 
     for y in range(size): 
      board[x][y][1] = Rectangle(Point(x*scale+scale*.05,y*scale+scale*.05),Point(x*scale+scale*.95,y*scale+scale*.95)) 
    for i in range(1): 
     selectTile(board, Point(randrange(size)*scale,randrange(size)*scale), size, color) 
    return board 

#selectTile does the action for selecting tiles 
#set color to 0 for black and white and 1 for color rotation 
def selectTile(board,point,size,color): 
    #sets value switch according to if colors are desired or not 
    if color == 1: 
     valueSwitch = colorSwitch 
    else: 
     valueSwitch = bwSwitch 
    x = int(point.getX()/scale) 
    y = int(point.getY()/scale) 
    #temp is made to preserve the selected tiles state 
    temp = board[x][y][0] 
    #swap all square values 
    #note try and except are also looped 
    for i in range(3): 
     for z in range(3): 
      try: 
       board[x-1+i][y-1+z][0] = valueSwitch(board[x-1+i][y-1+z][0]) 
      except: 
       #overlap fix for x maxed 
       if x == size - 1 and y != size - 1: 
        board[0][y-1+z][0] = valueSwitch(board[0][y-1+z][0]) 
       #overlap fix for y maxed 
       if y == size - 1 and x != size - 1: 
        board[x-1+i][0][0] = valueSwitch(board[x-1+i][0][0]) 
    #overlap fix for bottom right corner 
    if x == size - 1 and y == size - 1: 
     board[0][0][0] = valueSwitch(board[0][0][0]) 
     for a in range(2): 
      board[0][size-a-1][0] = valueSwitch(board[0][size-a-1][0]) 
      board[size-a-1][0][0] = valueSwitch(board[size-a-1][0][0])  
    #give middle square initial value again 
    board[x][y][0] = temp 

#updateBoard updates the squares to the right colour according to value   
def updateBoard(board, size, count): 
    if count != 0: 
     winsound.Beep(333, 200) 
    for x in range(size): 
     for y in range(size): 
      if board[x][y][0] == 0: 
       board[x][y][1].setFill('white') 
      elif board[x][y][0] == 1: 
       board[x][y][1].setFill('yellow') 
      elif board[x][y][0] == 2: 
       board[x][y][1].setFill('green') 
      elif board[x][y][0] == 3: 
       board[x][y][1].setFill('blue')     
      elif board[x][y][0] == 4: 
       board[x][y][1].setFill('black') 

#drawBoard draws the initial board  
def drawBoard(size, board, win):  
    for x in range(size): 
     for y in range(size): 
      board[x][y][1].draw(win)  
    return 

#checks to see if board is white(Winning condition) 
def winGame(board, size): 
    #steps through all x and y values 
    for x in range(size): 
     for y in range(size): 
      if board[x][y][0] != 0: 
       return 0 
    #returns true if no black squares are found 
    return 1 

#valueSwitch() just makes switching values easier by checking values and selecting the appropriate one 
def colorSwitch(value): 
    if value == 4: 
     return 0 
    else: 
     return value + 1 

#bwSwitch only selects from black and white value 
def bwSwitch(value): 
    if value == 4: 
     return 0 
    else: 
     return 4 

#winMessage() displaying a winning message graphic 
def winMessage(size, scale, win): 
    gameMessage = Text(Point(size*scale/2,size*scale/2),"You have won logic!") 
    gameMessage.setSize(int(scale/4)) 
    gameMessage.setTextColor('red') 
    gameMessage.draw(win)  

#gameMenu() is a menu to select game size 
def gameMenu(): 
    win = GraphWin("Logic Menu", 400, 600) 
    win.setBackground('light blue') 
    board = [[[Text(Point(0,0),'bleh'),Rectangle(Point(0,0),Point(200,200))] for y in range(3)] for x in range(2)] 
    #Making and drawing the buttons ;) 
    for x in range(2): 
     for y in range(3): 
      board[x][y][1] = Rectangle(Point(x*200+200*.05,y*200+200*.05),Point(x*200+200*.95,y*200+200*.95)) 
      board[x][y][1].draw(win) 
    board[0][0][0] = Text(board[0][0][1].getCenter(), 'Click for 5x5 puzzle') 
    board[1][0][0] = Text(board[1][0][1].getCenter(), 'Click for 7x7 puzzle') 
    board[0][1][0] = Text(board[0][1][1].getCenter(), 'Click for 9x9 puzzle') 
    board[1][1][0] = Text(board[1][1][1].getCenter(), 'Click for 12x12 puzzle') 
    board[0][2][0] = Text(board[0][2][1].getCenter(), 'Click to toggle colors') 
    board[1][2][0] = Text(board[1][2][1].getCenter(), 'Highscores!') 
    #drawing button options 
    for x in range(2): 
     for y in range(3): 
      board[x][y][0].draw(win) 
    #check to see what button is pressed 
    point = win.getMouse() 
    x = int(point.getX()/200) 
    y = int(point.getY()/200) 
    #colors is either 1 for colors or 0 for no colors 
    colors = 0 
    #turning colors on and off 
    #board[0][2][1] is the rectangle for colors 
    while y == 2: 
     if x == 0: 
      if colors == 0: 
       winsound.Beep(400, 200) 
       colors = 1 
       board[0][2][1].setFill('green') 
      else: 
       winsound.Beep(363, 200) 
       colors = 0 
       board[0][2][1].setFill('') 
     else: 
      winsound.Beep(400, 200) 
      board[1][2][1].setFill('red') 
      #board is just passed in for a smother button click effect not necessary for functionality 
      highscore_board(board) 
     point = win.getMouse() 
     x = int(point.getX()/200) 
     y = int(point.getY()/200) 
    board[x][y][1].setFill('red') 
    winsound.Beep(400, 200) 
    win.close() 
    if x == 0 and y == 0: 
     return 5 , colors 
    if x == 1 and y == 0: 
     return 7 , colors 
    if x == 0 and y == 1: 
     return 9 , colors 
    if x == 1 and y == 1: 
     return 12 , colors 
    return 5 , colors 

#highscore() checks to see if player has highscore and outputs a highscore to a text file 
def highscore(count): 
    #checks to see if highscore file exists 
    try: 
     scoreInfo = [line.strip() for line in open('highscore.txt')] 
     #remove all spacing 
     for i in range(scoreInfo.count('')): 
      scoreInfo.remove('') 
     scoreInfo[1] 
     scores = int(len(scoreInfo)/2) 
     newEntry = 0 
    #creates new highscore file is none exist 
    except: 
     win = GraphWin("Highscore!", 400, 200) 
     gameMessage = Text(Point(200,100),"Please input name: ") 
     gameMessage.setSize(int(scale/4)) 
     gameMessage.setTextColor('red') 
     gameMessage.draw(win) 
     name=inputWin() 
     f = open('highscore.txt', 'w') 
     f.write(name) 
     f.write('\n'+str(count)) 
     f.close() 
     gameMessage.setText(name+': '+str(count)+' - saved!') 
     time.sleep(1) 
     win.close() 
     return 

    #if there is a new highscore it is added at the beginning of the file 
    for i in range(scores): 
     if scores < 10 or count < int(scoreInfo[i*2+1]): 
      win = GraphWin("Highscore!", 400, 200) 
      gameMessage = Text(Point(200,100),"Please input name: ") 
      gameMessage.setSize(int(scale/4)) 
      gameMessage.setTextColor('red') 
      gameMessage.draw(win) 
      name=inputWin() 
      f = open('highscore.txt', 'w') 
      #max 10 highscores 9 + new highscore 
      if scores >= 10: 
       scores = 9 
      for i in range(scores): 
       try: 
        if count < int(scoreInfo[i*2+1]) and not newEntry: 
         f.write(name) 
         f.write('\n'+str(count)) 
         f.write('\n\n\n') 
         newEntry = 1 
        f.write(scoreInfo[i*2]) 
        f.write('\n') 
        f.write(scoreInfo[i*2+1]) 
        f.write('\n\n\n') 
       except: 
        pass 
      #if no entries have been added 
      #the new value is then added to the end 
      if newEntry == 0: 
       f.write(name) 
       f.write('\n'+str(count)) 
       f.write('\n\n\n') 
      f.close() 
      gameMessage.setText(name+': '+str(count)+' - saved!') 
      time.sleep(1) 
      win.close() 
      break 
    pass 

#board is just passed in for a smother button click effect not necessary for functionality  
def highscore_board(board): 
    win = GraphWin("Highscores", 200, 500) 
    win.setBackground('light green') 
    try: 
     scoreInfo = [line.strip() for line in open('highscore.txt')] 
     #remove all spacing 
     for i in range(scoreInfo.count('')): 
      scoreInfo.remove('') 
     Text(Point(50,20),"Highscores:").draw(win) 
     for i in range(10): 
      Text(Point(10,45*i+60),str(i+1)+'. ').draw(win) 
      try: 
       Text(Point(60,45*i+60),scoreInfo[i*2]).draw(win) 
       Text(Point(170,45*i+60),scoreInfo[1+i*2]).draw(win) 
      except: 
       pass 
    except: 
     Text(Point(100,250),"no scores yet.").draw(win) 
    time.sleep(.05) 
    board[1][2][1].setFill('') 
    #prevent program crash if scoreboard is exited through os 
    try: 
     win.getMouse() 
     winsound.Beep(363, 200) 
     win.close() 
    except: 
     winsound.Beep(363, 200) 

import tkinter as tk 

def getString(ment,mGui): 
    global hsname 
    hsname = ment.get() 
    mGui.destroy() 
    mGui.quit() 

def inputWin(): 
    mGui = tk.Tk() 
    ment = tk.StringVar() 

    mGui.title('New Highscore!') 
    mEntry = tk.Entry(mGui,textvariable=ment).pack(side=tk.LEFT) 
    mbutton = tk.Button(mGui,text='OK',command=lambda:getString(ment,mGui),fg='red',bg='blue').pack(side=tk.RIGHT) 
    mGui.mainloop() 
    return hsname 

這是部分這不會工作

import tkinter as tk 

def getString(ment,mGui): 
    global hsname 
    hsname = ment.get() 
    mGui.destroy() 
    mGui.quit() 

def inputWin(): 
    mGui = tk.Tk() 
    ment = tk.StringVar() 

    mGui.title('New Highscore!') 
    mEntry = tk.Entry(mGui,textvariable=ment) 
    mEntry.pack(side=tk.LEFT) 
    mbutton = tk.Button(mGui,text='OK',command=lambda:getString(ment,mGui),fg='red',bg='blue') 
    mbutton.pack(side=tk.RIGHT) 
    mGui.mainloop() 
    return hsname 

我只是胡鬧試圖使加入的高分更直觀的遊戲我做了這個代碼,它工作正常自身但是當我導入它甚至整個代碼複製到一個PY文件與其他功能它只是停止分配任何值我不明白:/

任何幫助表示讚賞

這是運行遊戲

#Josh Harrison 
#3008088 

from logic_game import * 

def playGame(): 
    option = gameMenu() 
    size = option[0] 
    color = option[1] 

    win = GraphWin("Logic Game", size*scale, size*scale) 
    win.setBackground('light pink') 
    board = setupBoard(size, color) 
    drawBoard(size, board, win) 
    countText = Text(Point(scale,scale/2),'moves: 0') 
    countText.setTextColor('red') 
    countText.draw(win) 
    count = 0 
    while not winGame(board, size): 
     updateBoard(board, size, count) 
     selectTile(board, win.getMouse(), size, color) 
     count += 1 
     countText.setText('moves: ' + str(count)) 
    updateBoard(board, size, count) 
    winMessage(size, scale, win) 
    highscore(count) 
    #pauses the window and waits for click before continuing 
    win.getMouse() 
    #closes the window "win" 
    win.close() 

playGame() 

鏈接graphics.py http://mcsp.wartburg.edu/zelle/python/graphics.py

+0

你需要給我們一個不起作用的程序的例子,而不是給我們一個可行的例子,然後試圖描述其他的例子。 – abarnert

+0

對不起,新的有一個更簡單的方法來上傳代碼,然後通過每行和間隔4次? – d4nk1337sauce

+1

是的,粘貼您的代碼,然後突出顯示它並點擊編輯器頂部的大括號按鈕,即可將突出顯示的文本格式化爲代碼。 –

回答

1

我不明白到底是什麼你的問題是做錯了的代碼,但我很確定我知道問題是什麼。

您的大部分程序都使用一些名爲graphics的庫來運行GUI。然後,您嘗試使用Tkinter在同一個程序中運行另一個GUI。

我不知道graphics這個庫是什麼,但除非它是構建在Tkinter之上,或者專門設計用於與Tkinter一起工作,否則這不太可行。他們都將嘗試負責您的程序的唯一GUI,處理來自用戶/窗口系統的所有事件,等等。其中一個或兩個都會失敗。

事實上,即使graphics建立在Tkinter頂部或設計與它一起工作,Tkinter窗口調用mainloop充其量下去,直到你退出該mainloop凍結您的GUI的其餘部分,並在最壞的情況下打破其他GUI依賴的外部mainloop

從我能從其他代碼中看到的那個graphics庫似乎有足夠的功能來完成您試圖用Tkinter做的所有事情 - 創建一個新窗口,在其上放置一些小部件,處理按鈕單擊。那麼,爲什麼不使用它呢?


現在,你已經給了我們一個鏈接到您正在使用的graphics庫......它看起來像一個瘦包裝Tkinter左右。這意味着您應該能夠輕鬆地整合它們。您只需創建一個新的Toplevel而不是根窗口(因爲graphics已經創建了一個Tkinter根),而不是調用mainloopquit(因爲您已經在由graphics創建的Tkinter主循環中)。

既然您沒有給我們一個SSCCE,我可以運行並破解,我已經在graphics文檔的第一個示例中構建了我自己的超級簡單文檔,它可以完成您正在嘗試執行的操作,並且還展示瞭如何與Tkinter代碼中的graphics窗口進行交互。

from graphics import * 
import Tkinter as tk 

def getString(ment,mGui): 
    global win 
    print(ment.get()) 
    mGui.destroy() 
    win.close() 

def inputWin(): 
    global hsname 
    mGui = tk.Toplevel() 
    ment = tk.StringVar() 

    mGui.title('New Highscore!') 
    tk.Entry(mGui,textvariable=ment).pack(side=tk.LEFT) 
    tk.Button(mGui,text='OK',command=lambda:getString(ment,mGui),fg='red',bg='blue').pack(side=tk.RIGHT) 
    win.getMouse() 

def main(): 
    global win 
    win = GraphWin("My Circle", 100, 100) 
    c = Circle(Point(50,50), 10) 
    c.draw(win) 
    win.getMouse() # Pause to view result 
    inputWin() 

main() 

這將是更好的重構這個以消除你的全局變量,無論是使用面向對象的設計(創建一個類,所以你可以存放東西的實例屬性)或一個功能的設計(通過關閉傳遞值或烤他們與lambda/partial一樣,因爲您已在執行Button命令),但我試圖按照您在代碼中已設置的樣式,而不是重寫所有內容。

+0

我試圖使用tkinter,因爲圖形沒有鍵盤處理和輸入使用終端只是有點跛腳。 實際上,如果任何人都可以幫助我一些非常好的終端輸入,那麼這看起來就像是最簡單的方法,如果它真的有效。 – d4nk1337sauce

+0

@ d4nk1337sauce:現在你告訴我們你正在使用的是什麼庫......它看起來像是建立在Tkinter之上的,它也是一個很薄的包裝,這意味着它應該可以讓它們一起工作。讓我看看,看看我能不能弄明白。 – abarnert