2016-06-27 15 views
1

次は、Python 3.0でのConwayのGame of LifeのPyCharm Community EditionにおけるTkinterを使用した不完全な実装です。Receive TypeError:オブジェクト.__新しい__()は、__new__が変更されていない場合はパラメータをとりません。

  • Cell.py:

    プログラムは、4つのファイルで構成され、細胞

  • Grid.pyのためのクラスが含まれています:ライフグリッド
  • Windows.pyのゲームのためのクラスが含まれています: Tkinterのレイアウトのためのクラス
  • main.pyに含まれています::スクリプト

Cell.pyを実行します
from random import randint 
from tkinter import * 

class Cell: 
    def __init__(self, master, state=None): 
     if state is None: 
      state = randint(0,2) 
     self.state = state 
     self.next_state = state 
     self.button = Button(master, width=2, height=1, bg = 'black' if self.state == 1 else 'white').pack(side=LEFT) 

    def __del__(self): 
     self.button.destroy() 

    def set_next_state(self, neighbours): 
     if self.state == 1: 
      self.next_state = 0 if neighbours < 2 or neighbours > 3 else 1 
     else: 
      self.next_state = 1 if neighbours == 3 else 0 

    def update(self): 
     self.state = self.next_state 
     self.button.config(bg = 'black' if self.state == 1 else 'white') 

Grid.py:

from tkinter import * 
from Cell import Cell 

class Grid: 
    def __init__(self, master, rows=15, cols=15, wraparound=True, pattern=None): 
     self.master = master 
     self.rows = rows 
     self.cols = cols 
     self.wraparound = wraparound 

     if len(self.pattern) == rows*cols: self.pattern = pattern 
     else: self.pattern = None 

     self.create_frames() 
     self.create_cells() 

    def create_frames(self): 
     self.frames = [Frame(self.master).pack(side=TOP) for r in range(self.rows)] 

    def destroy_frames(self): 
     for r in range(self.rows): 
      self.frames[r].destroy() 

    def create_cells(self): 
     self.cells = {} 
     for r in range(self.rows): 
      for c in range(self.cols): 
       if self.pattern is None: self.cells[(r,c)] = Cell(self.frames[r]) 
       else: self.cells[(r,c)] = Cell(self.frames[r], state=self.pattern[r*self.cols+c]) 

    def destroy_cells(self): 
     for r in range(self.rows): 
      for c in range(self.cols): 
       del self.cells[(r,c)] 

    def count_neighbours(self, r, c): 
     offsets = [(i,j) for j in range(-1,2) for i in range(-1,2)] 
     offsets.remove((0,0)) 
     neighbours = 0 
     for offset in offsets: 
      if self.wraparound: 
       neighbours += self.cells[((r+offset[0])%self.rows, (c+offset[1])%self.cols)].state 
      else: 
       if r+offset[0] >= self.rows or r+offset[0] < 0 or c+offset[1] >= self.cols or c+offset[1] < 0: 
        neighbours += 0 
       else: 
        neighbours += self.cells[(r+offset[0], c+offset[1])].state 
     return neighbours 

    def calculate_next_state(self): 
     for r in range(self.rows): 
      for c in range(self.cols): 
       neighbours = self.count_neighbours(r,c) 
       self.cells[(r,c)].set_next_state(neighbours) 

    def update_cells(self): 
     for r in range(self.rows): 
      for c in range(self.cols): 
       self.cells[(r,c)].update() 

    def step(self): 
     self.calculate_next_state() 
     self.update_cells() 

    def load_pattern(self, rows=10, cols=10, wraparound=True, pattern=None): 
     self.destroy_cells() 
     self.destroy_frames() 

     self.rows = rows 
     self.cols = cols 
     self.wraparound = wraparound 
     self.pattern = pattern 

     self.create_frames() 
     self.create_cells() 

Windows.py:

from Grid import Grid 
from tkinter import * 

class MainWindow: 
    def __init__(self, rows=10, cols=10, wraparound=True, pattern=None): 
     self.root = Tk() 

     grid_frame = Frame(self.root).pack(side=TOP) 
     self.grid = Grid(grid_frame, rows=rows, cols=cols, wraparound=wraparound, pattern=pattern) 

     button_frame = Frame(self.root).pack(side=BOTTOM) 
     self.time_interval = 1000 
     self.start_stop_button = Button(button_frame, text='START', command=self.start_stepper).pack(side=LEFT) 
     self.step_button = Button(button_frame, text='STEP', command=self.grid.step) 

     self.menubar = Menu(self.root) 
     self.menubar.add_command(label='Change Time Interval', command=self.change_time_interval) 
     self.root.config(menu=self.menubar) 

     self.root.mainloop() 

    def change_time_interval(self): 
     # Incomplete 
     pass 

    def start_stepper(self): 
     # Incomplete 
     pass 

    def stop_stepper(self): 
     # Incomplete 
     pass 

main.py:

from Windows import MainWindow 
game = MainWindow() 

私は次の出力を得るmain.py私は実行:

出力:私はデフォルト__new__メソッドを上書きすることはありませんよう

Traceback (most recent call last): 
    File "C:/Users/Tyler/PycharmProjects/GameOfLife/main.py", line 3, in <module> 
    game = MainWindow() 
    File "C:\Users\Tyler\PycharmProjects\GameOfLife\Windows.py", line 9, in __init__ 
    self.grid = Grid(grid_frame, rows=rows, cols=cols, wraparound=wraparound, pattern=pattern) 
TypeError: object.__new__() takes no parameters 

私はこれで私の知恵の最後にしています。このタイプの他のすべてのスタックオーバーフロー問題を確認した後、ほとんどの解決策は、__init__から__init__までのスペルを修正していました。私はPythonスクリプティングには比較的新しいので、なぜエラーが生成されたのかについての解説でこれをデバッグする助けが最も高く評価されます。

+0

すべての問題は、* Tkinter.Grid()クラスをオーバーライドして*発生します。 'Grid()'クラスの名前を変更する必要があります。 –

答えて

4

Tkinterには、独自のクラスをインポートした後にfrom tkinter import *を使用したため、同じ名前の自分のクラスをシャドーするGridというクラスがあります。

いくつかの可能な解決策があります。

    from Grid import Grid as MyGridにインポートを変更し、独自のグリッド・クラスを使用する場合 MyGridを呼び出し
  1. from Grid import Gridのインポートをtkinterの後に移動します(tkinter Gridクラスを使用する必要がない限り)。
  2. は何か他のものになど
  3. 変更、tkinter.Frameで(フレームなど)import tkinterとアクセスTkinterのクラスにクラスの名前を自分のTkinterのインポートを変更します。
+0

いつものように、これはとても明白です。どうもありがとうございました。 – Chubzorz

+1

それで、tkinterでも 'import *'を使わないのです。 – user2357112

+1

@Chubzorz一般的な方法は、 'tkinter as tk'を実行することです。スターの輸入を避けるその他の理由については、http://stackoverflow.com/a/37511018/4014959をご覧ください。 –

関連する問題