1

私はプログラミング、Python、このウェブサイト、そして実際にこれらの種類のウェブサイトを一般的に使用するのは初めてなので、聞いてください.

tkinter モジュールと ttk モジュールを使用してより大きなプログラムのモジュールを作成してきましたが、独自のモジュールをメイン プログラムにインポートすると、何らかの理由で ttk の機能が正常に動作しません。つまり、表示されますが、私が書いたスタイル (s=ttk.Style(); s.configure...など) はとにかくそれを変更しません。モジュールを単独で実行すると、すべて正常に動作します。メインプログラムにインポートされると、そうではありません。

これだけでなく、入力ボックスを使用するとき、たとえばテキスト変数として var=StringVar() を使用して、それらを使用するように言われた方法を発見しただけです (モジュールが単独で実行)、var.get() が呼び出されたときに変数 var を空のままにするようになりました。今、私は StringVar() のすべての言及を削除するだけでこれをソートしました (これらが実際にどれほど冗長であるかを知りたいです)が、メインプログラムにそれらをインポートすると、それらがひどく誤動作する理由を知りたいです. サンプルコードをいくつか紹介しますが、十分に選択するのに苦労するものがたくさんあります...

アドバイスをいただければ幸いです。

編集:このようなものをあなたに与えることは役に立ちましたか?

stackoverflowmodule.py

import sys
from tkinter import *
from tkinter import ttk
import time
from random import randint, choice

class Decimals():
    def Question1(self):
        DECFrame.destroy()
        frame1=ttk.Frame(DECmaster, height=height, width=width, style="NewFrame.TFrame")
        frame1.pack()
        Q1Label=ttk.Label(frame1, text="Question 1:", style="TitleLabel.TLabel")
        Q1Label.grid(column=0, row=0, pady=(50,0))     
        answer=StringVar()
        entry1=ttk.Entry(frame1, textvariable=answer)
        entry1.grid(column=0, row=1, pady=(200,0))
        # Typing in Hello should give a correct answer.
        def Question1Attempt():            
            attempt=answer.get()            
            if attempt!="Hello":
                print("Incorrect")
            else:
                print("Correct")
        button=ttk.Button(frame1, text="Ok", command=Question1Attempt)
        button.grid(column=0, row=2, pady=(30,0))


def Start():
    global DECmaster
    global s
    global DECFrame
    global DEC
    global width
    global height
    DECmaster = Tk()

    width=str(1000)
    height=str(800)
    x1=str(0)
    y1=str(0)

    DECmaster.geometry(width+"x"+height+"+"+x1+"+"+y1)
    DECmaster.configure(bg="#8afff0")

    s=ttk.Style()
    s.configure("NewFrame.TFrame", background="#8afff0")
    s.configure("TitleLabel.TLabel", foreground= "blue", background="#8afff0")

    DECFrame=ttk.Frame(DECmaster, style="NewFrame.TFrame")
    DECFrame.pack()

    TitleLabel=ttk.Label(DECFrame, text="Test for Decimals", style="TitleLabel.TLabel")
    TitleLabel.grid(column=1, row=0, pady=(50,0), sticky=N)

    DEC=Decimals()
    button=ttk.Button(DECFrame, text="Start", command=DEC.Question1)
    button.grid(column=2, row=2, pady=(200,0), sticky=N)

    DECmaster.mainloop()

stackoverflowprogram.py

from tkinter import *
from tkinter import ttk
import time
import stackoverflowmodule



root = Tk()

width=str(1000)
height=str(800)
x1=str(0)
y1=str(0)
##width=str(1228)
##height=str(690)
##x1=str(-1)
##y1=str(-22)

root.geometry(width+"x"+height+"+"+x1+"+"+y1)
root.configure(bg="#8afff0")

s=ttk.Style()
s.configure("NewFrame.TFrame", background="#8afff0")
s.configure("TitleLabel.TLabel", foreground= "blue", background="#8afff0")

Testframe=ttk.Frame(root, height=height, width=width, style="NewFrame.TFrame")
Testframe.pack()
Titlelabel=ttk.Label(Testframe, text="Start Test:", style="TitleLabel.TLabel")
Titlelabel.grid(column=0, row=0, pady=(50,0))

def StartTest():
    stackoverflowmodule.Start()


button=ttk.Button(Testframe, text="Start", command=StartTest)
button.grid(column=0, row=1, pady=(100,0))

root.mainloop()

そこには非常に多くのことがあることに気づきましたが、それがなければ私の主張を実際に示すことはできませんでした. 再度、感謝します。

4

2 に答える 2

1

のインスタンスを 2 つ作成することはできませんtkinter.Tk。そうすれば、2 つのうちの 1 つが起こります。

スクリプト内のコードのほとんどは、モジュールが終了するのを待っているため、実行されない可能性がありmainloopます。これは終了するまで発生しません。

構造を変えると、Tkインスタンスが 2 つになり、そのうちの 1 つだけが実際に実行されます。スクリプト内のコードの一部は、たまたま正しいTkインスタンス (またはカバーの下にある正しい実際の Tk オブジェクト) を見つけます。これは、1 つの Tk が「どこかまたは他の場所」にあると想定し、なんとか見つけられる共有グローバル要素がたくさんあるためです。しかし、他のコードは間違ったものを見つけてしまい、何の効果もありません。または、場合によっては、何かが間違った結果をもたらしたり、クラッシュを引き起こしたりすることがあります。

トップレベルのアプリケーションを、それを使用するモジュールまたはスクリプトのいずれか 1 つの場所に配置し、そこから別の場所にアクセスさせる必要があります。


Tkこれを行う 1 つの方法は、モジュールのコードをインスタンスで呼び出すことができるようにモジュールを作成することです。次に、この__main__トリックを使用して、モジュールを (別のスクリプトからインポートするのではなく) スクリプトとして直接実行すると、Tkインスタンスが作成され、そのコードが呼び出されます。これは本当に簡単な例です。

tkmodule.py:

from tkinter import *

def say_hi():
    print("Hello, world!")

def create_interface(window):
    hi = Button(window, text='Hello', command=say_hi)
    hi.pack()

if __name__ == '__main__':
    root = Tk()
    create_interface(root)
    root.mainloop()

tkscript.py:

from tkinter import *
import tkmodule

i = 0
def count():
    global i
    i += 1
    print(i)

def create_interface(window):
    countbtn = Button(window, text='Count', command=count)
    countbtn.pack()

root = Tk()
create_interface(root)
window = Toplevel(root)
tkmodule.create_interface(window)
root.mainloop()

を実行するtkscript.pyと、1 つのインスタンスが所有され、それがTk自身のインスタンスと に渡さcreate_frametkmodule.create_frameます。しかし、単に を実行するtkmodule.pyと、それはインスタンスを所有し、Tkそれを独自の に渡しますcreate_frame。いずれにせよ、1 つのTkインスタンスと 1 つのメイン ループがあり、誰もがそれを使用できます。

2 つのトップレベル ウィンドウが必要な場合は、Toplevelどこかに明示的に作成する必要があることに注意してください。(また、モジュール自体を実行すると、新しいウィンドウが作成され、既定のウィンドウは空のままになります。)tkmodule.py


もちろん、これを行うより簡単な方法は、すべての GUI 要素を独自のインスタンスを作成しないTkモジュールに配置し、適切なモジュールをインポートしてそれらを駆動するスクリプトを作成することです。

于 2013-05-13T22:30:16.927 に答える