4

私は Python の初心者で、これが私の最初の言語です。私は、すぐに大きくなりすぎて、終わらせなければならないことを把握できないという任務を負っています。私はほとんど終わりました。この時点で、メイン メニューとして機能するダイアログ ボックス、テストを実行するメイン メニューから選択可能なオプションであるダイアログ ボックス、およびテストを実行するマルチスレッド インスタンスが「しばらくお待ちください」を開くダイアログ ボックスを作成しました。テストが終了すると、テストの完了を宣言する別のダイアログ ボックスが表示されます。

私の問題: [テストの実行] ダイアログ内で、マルチスレッド インスタンスを呼び出すボタンを作成しようとしています。他の人の助けを借りて解析したコードから、[テストの実行] ダイアログ ボックス内でインスタンス化するクラスがわかりません。

私のスレッド化の実装が間違っていると思い始めています。ただし、方法はあるはずです。

これは私が呼び出そうとしているモジュールです。

from slice_setup import SLICE_SETUP
import Tkinter as tk
import threading
import Queue


class GuiPart:
    def __init__(self, master, queue):
        self.queue = queue
        self.master = master
        self.master.geometry("300x100+400+250")
        self.master.title("RSAM BCT")
        tk.Label(master, text="REDCOM SLICE", fg="red").pack()
        tk.Label(master, text="BCT - Basic Configuration Test", fg= "red").pack()
        tk.Label(master, text="Please wait...", fg= "black").pack()
        tk.Label(master, text="Estimated time: 3 min 6 sec", fg= "black").pack()

    def processIncoming(self):
        while self.queue.qsize():
            try:
                text = self.queue.get(0)
                Complete(self.master, text)
            except Queue.Empty:
                pass

class ThreadedClient:
    def __init__(self, master):
        self.master = master
        self.queue = Queue.Queue()
        self.gui = GuiPart(master, self.queue)
        self.running = True
        self.thread = threading.Thread(target=self.workerThread1)
        self.thread.start()
        self.periodicCall()

    def periodicCall(self):
        self.gui.processIncoming()
        if not self.running:
            return
        self.master.after(100, self.periodicCall)

    def workerThread1(self):
        obj_rcs = SLICE_SETUP()
        obj_rcs.SLICE()
        self.queue.put("Configuration Complete!")
        self.running = False

class Complete(tk.Toplevel):
    def __init__(self, master=None, completetext=""):
        tk.Toplevel.__init__(self, master)
        self.geometry("400x300+400+250")
        self.title("RSAM BCT")
        tk.Label(self, text="REDCOME SLICE", fg="red").pack()
        tk.Label(self, text="BCT - Basic Configuration Test", fg="red").pack()
        tk.Label(self, text=completetext, fg="dark green").pack()
        tk.Label(self, text="Trunk 1: Port 1: Phone 1: 760-450-4500", fg="black").pack()
        tk.Label(self, text="Trunk 1: Port 2: Phone 2: 760-450-4501", fg="black").pack()
        tk.Button(self, text="    Exit    ", command=self.destroy).pack()


if __name__ == "__main__":
    root = tk.Tk()
    client = ThreadedClient(root)
    root.mainloop()

そして、これは私が電話しようとしている場所です:

import sys
import Tkinter as Tk()
from bct_pleasewait import ????
import threading
import Queue
import time
sGui = Tk()

class slice_menu:

    def runtest(self):
        obj_wait = ????
        obj_wait.????

    def slicemenu(self):
        sGui.geometry("400x300+400+250")
        sGui.title("RSAM BCT")
        Label(sGui, text= "REDCOM SLICE", fg="red").pack()
        Label(sGui, text= "BCT - Basic Configuration Test", fg= "red").pack()
        Label(sGui, text= "-Ensure you are logged off of HyperTerminal", fg= "black").pack()
        Label(sGui, text= "-Turn on your REDCOM SLICE unit",
        fg= "black").pack()
        Label(sGui, text= "-Please connect your laptop to SLICE CONSOLE", fg= "black").pack()
        Label(sGui, text= "-This configuration will take 3 minutes", fg= "black").pack()
        Button(sGui, text = "     Run     ", command = self.runtest).pack()
        Button(sGui, text = "  Exit test  ", command = sGui.destroy).pack()
        sGui.mainloop()

このクラスにはまだ小さなエラーがありますが、最初にこの問題を解決したいと思っています。

4

1 に答える 1

0

具体的な答えではありませんが、あなたの質問は非常に広いです。

心に留めておくべきいくつかの点:

  • Tk はスレッドセーフではありません。つまり、Tk 呼び出しはメイン スレッドからのみ呼び出す必要があります。他のスレッドに GUI 以外の作業をさせても問題ありません。
  • CPython では、Global Interpreter Lock ("GIL") により、一度に 1 つのスレッドのみが Python バイトコードを実行できます。そのため、非 GUI スレッドによって GUI が応答しなくなる可能性があります。

一度に 1 つのテストのみを実行し、そのテストを細かく分割できる場合は、タイムアウト (アラーム ハンドラとも呼ばれます) を使用できます。このハンドラーは少し作業を行い、その状態を保存し、進行状況ダイアログを更新して終了し、再度呼び出されるのを待ちます。

テストが長時間実行され、GUI の応答性を維持したい場合は、スレッド化の代わりにマルチプロセッシングを使用することをお勧めします。別のプロセスでテストを開始し、キューやセマフォなどを使用して、GUI プロセスと非 qui プロセスの間で通信します。

于 2013-07-19T13:09:15.730 に答える