就是自己想用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)
於是我突然想到,是跟類屬性有關的東西哦,所以查了一下,這個屬性應該將前面的_,去掉