macOS 上的 tkinter 需要移动鼠标才能正常运行

问题描述 投票:0回答:1

我有一个用 python 3.10 编写的用于 tkinter 应用程序的自动化测试工具。我为 tkinter GUI 应用程序编写了一系列测试,它们都运行良好并在 Ubuntu 22.04 上通过。

我在 macos Sonoma 14.5 上运行它,它可以工作。测试的运行有很长的滞后。如果我将鼠标移动到屏幕上的任何位置(不仅仅是在 GUI 中),那么它会以正常速度运行,没有延迟。所有测试都通过,因此测试操作正在发生并正确运行,只是有滞后

  • 我尝试在多个地方添加 .update() 和 .update_idletasks() 。没有喜悦。
  • 我尝试为根窗口和测试脚本更新的各个小部件添加它们。没有喜悦。

注意:在没有测试工具的情况下运行应用程序可以正常工作,但是我通常会移动鼠标来实现这一点,所以我无法真正判断鼠标移动是否正在“修复”它,或者存在一些隐藏的错误测试工具行为(同样,在 Ubuntu 中运行良好)

不确定下一步要尝试什么。任何提示或线索将不胜感激。

仅供参考测试线束拱门

测试工具具有客户端-服务器架构。服务器在 GUI 应用程序内部运行,并等待传入的套接字连接和运行命令。客户端在 pytest 框架中运行以执行基本操作,例如:获取当前屏幕内容、单击按钮、获取小部件内容、获取小部件状态(例如禁用)

python-3.x tkinter
1个回答
0
投票

参见 Tkinter GUI 仅在鼠标移动时更新

按照上面帖子中的说明,我使用 window.after() 函数在 tkinter 线程上调用测试函数,而不是测试工具线程,现在它可以在 macOS 和 Ubuntu 上运行。

# server class gets requests from individual test cases 
# e.g. cmd='click_left'
class GuiApiServer:
   <snip>
   # this runs in the test harness thread
   def _callback(self, command):
       # all commands sent here should be json
       cmd = json.loads(command)
       # the id should indicate the server thread id
       svc.logger.info(f'server      : callback: cmd={cmd["cmd"]: <10} '
                       f'id={threading.get_ident()}')
       svc.guiapi.run_callback(cmd)


# this class holds all of the test code that interacts with
# tkinter widgets
class GuiApiTinker:
    # this runs in the class that has all of the tkinter window
    # info. self_window is the root window
    def run_callback(self, cmd):
        if self._window is not None:
            # cause the server callback to run under the tkinter thread
            self._window.after(1, svc.server.tkinter_callback, cmd)

# in the server class again 
class GuiApiServer:
   <snip>
   def tkinter_callback(self, cmd, is_invalid):
      # temp code to see how long it takes to get back here
      # when .after() is called
      elapsed = time.time() - self._last_time
      self._last_time = time.time()

      # the id should indicate the tkinter thread id
      svc.logger.info(f'tkinter_cb  : {elapsed: >0.3f}  '
                      f'cmd= {cmd["cmd"]: <10} '
                      f'id={threading.get_ident()}')

      if cmd['cmd'] == 'click_left':
         rsp = svc.guiapi.click_left(cmd)
         self.send(rsp)
      <snip other commands> 

完整代码在这里: https://bitbucket.org/arrizza-public/gui-api-tkinter/src/master/

有关服务器端的内容,请参阅 gui_api_tkinter/lib/guiapi/ 文件。 有关如何使用它的示例,请参阅示例/和版本/

© www.soinside.com 2019 - 2024. All rights reserved.