【问题标题】:Threading with Twisted with Tkinter使用 Tkinter 进行 Twisted 线程
【发布时间】:2016-05-15 17:41:43
【问题描述】:

我目前正在开发一个使用 tkinter 作为 UI 的 Battleship 游戏项目(用于学习目的),并且因为我希望该程序能够在两台计算机上运行以进行多人游戏,并为数据传输而扭曲。这是我第一次使用twisted,但是我已经多次使用tkinter。

我知道 twisted 和 tkinter 都在循环中运行,因此通常不可能让它们在同一个线程中运行。所以我发现有两种方法可以解决这个问题:tksupport 和在单独的线程中运行twisted 的reactor

但是,我尝试从twisted.internet 导入tksupport,但它说它不存在。我检查了我的站点包中的扭曲文件夹以确保它确实不存在,但即使是扭曲的文档也声称它存在。我假设这是因为我正在运行 python 3.5 并且 tksupport 尚未被移植,但如果不是这种情况,请告诉我。

另外,关于线程的解决方案,我发现将twisted的reactor放在它自己的线程中存在一些争议。 是否可以将reactor 放在自己的线程中,如果可以,我应该采取哪些预防措施?

谢谢。

【问题讨论】:

  • 根据我的记忆,战舰是一款回合制游戏,玩家可以在等待对方消息的同时冻结一个玩家的屏幕。如果是这样,我会考虑使用套接字来避免异步消息传递的复杂性。
  • @TerryJanReedy 是的,但就像我说的,这是出于学习目的。基本上我是故意让它变得比必要的更复杂,这样我就可以学习如何使用twisted。但我也在尝试使用twisted 实现游戏内聊天。基本上我打算有两个听众,一个用于聊天,一个用于游戏数据。虽然您认为游戏数据可以与简单的同步套接字一起使用是正确的,但聊天数据需要是异步的。

标签: python python-3.x tkinter twisted


【解决方案1】:

我查看了twisted.internet.tksupport 的源代码,它似乎没有被移植以支持 Python 3。罪魁祸首是导入 tkinter 模块的行:

import tkSimpleDialog, tkMessageBox

在 Python 3 中相当于:

from tkinter import simpledialog, messagebox

要在 Twisted 支持 Python 3 的 Tkinter 之前解决这个问题,您应该能够创建自己的 tksupport 模块:

# tksupport.py
from tkinter import simpledialog, messagebox
from twisted.internet import task

_task = None

def install(widget, ms=10, reactor=None):
    """Install a Tkinter.Tk() object into the reactor."""
    installTkFunctions()
    global _task
    _task = task.LoopingCall(widget.update)
    _task.start(ms / 1000.0, False)

def uninstall():
    """Remove the root Tk widget from the reactor.

    Call this before destroy()ing the root widget.
    """
    global _task
    _task.stop()
    _task = None

def installTkFunctions():
    import twisted.python.util
    twisted.python.util.getPassword = getPassword

def getPassword(prompt = '', confirm = 0):
    while 1:
        try1 = simpledialog.askstring('Password Dialog', prompt, show='*')
        if not confirm:
            return try1
        try2 = simpledialog.askstring('Password Dialog', 'Confirm Password', show='*')
        if try1 == try2:
            return try1
        else:
            messagebox.showerror('Password Mismatch', 'Passwords did not match, starting over')

__all__ = ["install", "uninstall"]

按照 Twisted 的 Tkinter example 稍作修改的版本,您可以这样做:

import tkinter as tk
from twisted.internet import reactor

import tksupport

root = tk.Tk()

# Install the Reactor support
tksupport.install(root)

# at this point build Tk app as usual using the root object,
# and start the program with "reactor.run()", and stop it
# with "reactor.stop()".

【讨论】:

  • 所以这是twisted的tksupport的相同实现,只使用tkinter 3.x兼容导入?
  • @RobertR 是的,完全正确。
【解决方案2】:

我目前已经扭曲了 17.9.0 和 python 3.6。 参考上面的答案, python 3 的 tksupport 现在可用于 twisted,因此无需创建自己的 tksupport 模块。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-08-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-30
    相关资源
    最近更新 更多