前言

就是自己想用python做一个聊天室,然后看看socket库,websocket库,有点底层,然后也会用到协程的东西,不是很明白,一时间也不知道怎么写,然后就用了封装好的python-socketio来实现,做好了以后,跟同学用,被吐槽说滚轮不会自动下滑到底部,难用,于是我找天找地,在网上啥也没找到,经过自己一个多小时的摸索,终于找到了解决方法
想看看聊天室代码的话,可以到https://github.com/cgynb/a-flask-project/tree/guiChatroom看看。或者直接访问这个地址

http://81.70.180.118:12347/聊天呀.exe

是打包好的程序,服务端有在服务器上跑着了,可以直接使用的,但是低版本的windows运行可能会有点问题
请添加图片描述

需求

基本功能实现了之后,跟同学用,被吐槽说滚轮不会自动下滑到底部,难用,于是我找天找地,在网上啥也没找到,经过自己一个多小时的摸索,终于找到了解决方法

在聊天窗口和当前用户列表使用了ScrollText这个控件,但是当有新的消息的时候,我们希望能看到最新的消息,所以就需要我们设置将滚动条拉到底部,但是这样是很糟糕的体验,所以需要界面自动拉动
聊天信息窗口和用户列表的代码如下

        # 会话框
        self.msg_box = ScrolledText(self.window, width=100, height=22)
        self.msg_box.autohide_scrollbar()
        self.msg_box.place(x=30, y=60)

        # 用户列表
        self.user_list = ScrolledText(self.window, width=24, height=15)
        self.user_list.autohide_scrollbar()
        self.user_list.place(x=780, y=0)
        self.user_list.insert('end', '在线用户:')

解决过程

我查了一下源码,于是我吃惊的发现ScrollText这个控件竟然是Scrollbar和Text控件组合在一起的,所以我就想应该是在滚动条(Scrollbar),这个类应该是有一个方法可以调整的,找了半天,没找到。所以我就把目光放在了Text上,果然就是这样的

具体解决

根据官方文档引入ScrollText

from ttkbootstrap.scrolled import ScrolledText

然后Ctrl+鼠标左键,可以看到ScrollText源码,在__init__函数中会发现这样的初始化

        # setup text widget
        self._text = ttk.Text(self, padx=50, **kwargs)

然后Ctrl+鼠标左键单机Text

class Text(Widget, XView, YView):

我们会发现,这个Text类继承了YView这个类,还有XView,那么联想一下,可以猜到可能就是这个YView跟文本展现的位置有关,所以我们Ctrl+鼠标左键YView

class YView:
    """Mix-in class for querying and changing the vertical position
    of a widget's window."""

    def yview(self, *args):
        """Query and change the vertical position of the view."""
        res = self.tk.call(self._w, 'yview', *args)
        if not args:
            return self._getdoubles(res)

    def yview_moveto(self, fraction):
        """Adjusts the view in the window so that FRACTION of the
        total height of the canvas is off-screen to the top."""
        self.tk.call(self._w, 'yview', 'moveto', fraction)

    def yview_scroll(self, number, what):
        """Shift the y-view according to NUMBER which is measured in
        "units" or "pages" (WHAT)."""
        self.tk.call(self._w, 'yview', 'scroll', number, what)

用咱们悲伤的英文一看,诶,有个yview_moveto方法,这一看就是移动文本位置的方法呀

所以我展示消息的函数就是这么写的

    def show_msg(self, username, message):
        if message:
            self.msg_box.insert('end', '\n' + username + ':' + '\n   ' + message)
            self.msg_box.text.yview_moveto(1)

这边其实有个python基础的小细节,就是在ScrollText源码中可以发现,他那个类属性是这么写的

self._text = …

但是为什么在我的代码中是这样的呢

self.msg_box.text.yview_moveto(1)

于是我突然想到,是跟类属性有关的东西哦,所以查了一下,这个属性应该将前面的_,去掉

Logo

致力于链接即构和开发者,提供实时互动和元宇宙领域的前沿洞察、技术分享和丰富的开发者活动,共建实时互动世界。

更多推荐