tkinter-TinUI-xml实战(9)crosschat客户端

news2024/12/28 22:51:11

tkinter-TinUI-xml实战(9)crosschat客户端

  • 引言
  • 声明
  • 文件结构
  • 核心代码
    • 服务端连接
    • 登录界面
    • 主页面
    • 主文件
  • 结语

引言

CrossChat(十字街)是一个线上匿名群聊平台,类似Hack.Chat

现在通过websocket简单地构建一个cc的客户端。有以下几点注意:

  1. 只提供代码和基础思路,不提供代码功能详解

  2. 仅作为学习使用,不具备应用功能


声明

本项目属于作者原创。借鉴了GitHub/TinUI上的tuxml.py,翻版必究,但可以自行添加功能代码。

本项目使用的TinUI为我开源并维护在GitHub上的主文件——TinUI.py。当然,使用PYPI中下载安装的tinui也可以。


文件结构

在这里插入图片描述

  • crosschat.py - 参考hackchat.py

  • crosschat客户端.pyw - 主文件

  • loadin.xml - 聊天区登录界面

  • main.xml - 主页面


核心代码

服务端连接

参考pypi上的hackchat包,建立websocket连接。crosschat.py。

import json
import threading
import time
import websocket

class CrossChat:
    """A library to connect to https://cross.chat/
    """

    def __init__(self, nick, channel="programming"):
        """Connects to a channel on https://cross.chat.

        Keyword arguments:
        nick -- <str>; the nickname to use upon joining the channel
        channel -- <str>; the channel to connect to on https://hack.chat/
        """
        self.nick = nick
        self.channel = channel
        self.online_users = []
        self.on_message = []
        self.on_join = []
        self.on_leave = []
        self.ws = websocket.create_connection("wss://ws.crosst.chat:35197/")
        self._send_packet({"cmd": "join", "channel": channel, "nick": nick})
        threading.Thread(target = self._ping_thread).start()

    def send_message(self, msg):
        """Sends a message on the channel."""
        self._send_packet({"cmd": "chat", "text": msg})

    def _send_packet(self, packet):
        """Sends <packet> (<dict>) to https://cross.chat."""
        encoded = json.dumps(packet)
        self.ws.send(encoded)

    def run(self):
        """Sends data to the callback functions."""
        while True:
            result = json.loads(self.ws.recv())
            if result["cmd"] == "chat" and not result["nick"] == self.nick:
                for handler in list(self.on_message):
                    handler(self, result["text"], result["nick"])
            elif result["cmd"] == "onlineAdd":
                self.online_users.append(result["nick"])
                for handler in list(self.on_join):
                    handler(self, result["nick"])
            elif result["cmd"] == "onlineRemove":
                self.online_users.remove(result["nick"])
                for handler in list(self.on_leave):
                    handler(self, result["nick"])
            elif result["cmd"] == "onlineSet":
                for nick in result["nicks"]:
                    self.online_users.append(nick)

    def _ping_thread(self):
        """Retains the websocket connection."""
        while self.ws.connected:
            self._send_packet({"cmd": "ping"})
            time.sleep(60)

登录界面

其实很简单,就是输入房间号和昵称。loadin.xml。

<!--TinUIXml编辑器-->
<tinui>
    <line y="15">
        <line>
            <paragraph text="chat room id"></paragraph>
        </line>
        <line>
            <paragraph text="nick name"></paragraph>
        </line>
        <back></back>
        <line>
            <entry width="210">roomide</entry>
        </line>
        <line>
            <entry width="210">nicknamee</entry>
        </line>
    </line>
    <line x="60">
<paragraph text="             "></paragraph>
        <button2 text="清空" command='self.funcs["cleanover"]'></button2>
        <paragraph text="                        "></paragraph>
        <button2 text="进入" command='self.funcs["login"]'></button2>
    </line>
</tinui>

在这里插入图片描述

主页面

main.xml。

<!--TinUIXml UI界面布局-->
<!--TinUIXml UI界面布局-->
<tinui>
    <line>
        <line>
            <ui width="650" height="460" scrollbar="True">content</ui>
        </line>
        <line>
            <textbox width="650" height="180" scrollbar="True">textbox</textbox>
        </line>
        <line>
            <paragraph text="                                                                                                " width="1000"></paragraph>
            <button2 text="发送文本(Ctrl+Enter)" command='self.funcs["sendmsg"]'></button2>
        </line>
        <back></back>
        <line>
            <button2 text="使用须知📝" command='self.funcs["aboutuse"]'></button2>
            <button2 text="关于应用🔎" command='self.funcs["aboutccpy"]'></button2>
            <button2 text="注意事项❗" command='self.funcs["warnccpy"]'></button2>
        </line>
        <line>
            <link text="基于hack.chat开发" url="https://hack.chat/"></link>
        </line>
        <line>
            <ui width="360" height="610">aboutui</ui>
        </line>
    </line>
</tinui>

在这里插入图片描述

主要的功能UI部分在左边,右边只是给出了可能的附加功能,因此在接下来的主文件中实际上是没有相应的功能代码片段的。

主文件

from tinui import *
from tkinter import Tk
import crosschat
import threading

def endy():
    bbox=content.bbox('all')
    if bbox==None:
        return 0
    else:
        return bbox[-1]
def addhere(t):
    content.add_paragraph((645,endy()+5),fg='#b48ead',text=nickname,anchor='ne')
    content.add_paragraph((645,endy()+1),text=t,anchor='ne')
def addthere(t,s):
    content.add_paragraph((5,endy()+5),fg='#8fa1b3',text=s,anchor='nw')
    content.add_paragraph((5,endy()+1),text=t,anchor='nw')
def addinfo(t):
    ...

def sendmsg(*e):#
    context=textbox.get(1.0,'end')
    addhere(context)
    ccc.send_message(context)
    textbox.delete(1.0,'end')

def aboutuse(*e):#
    ...

def aboutccpy(*e):#
    ...

def warnccpy(*e):#
    ...

def message_got(chat, message, sender):
    addthere(message,sender)

root=Tk()
root.geometry('1100x700+5+5')
root.title('CrossChat客户端')

u=BasicTinUI(root)# main ui
u.pack(fill='both',expand=True)
x=TinUIXml(u)
#in
x.funcs["sendmsg"] = sendmsg
x.funcs["aboutuse"] = aboutuse
x.funcs["aboutccpy"] = aboutccpy
x.funcs["warnccpy"] = warnccpy
#during
with open('main.xml',mode='r',encoding='utf-8') as f:
    xml=f.read()
x.loadxml(xml)
#out
#out
content = x.tags["content"][0]#ui - main content chat
textbox = x.tags["textbox"][0]#textbox - text to chat
aboutui = x.tags["aboutui"][0]#ui - about view of ccpy

u.pack_forget()
#-----

logu=BasicTinUI(root,width=400,height=300)# log ui
logu.pack()
lx=TinUIXml(logu)
#in
def cleanover(*e):#
    roomide.delete(0,'end')
    nicknamee.delete(0,'end')
def login(*e):#
    global ccc,nickname
    logu.pack_forget()
    roomid=roomide.get()
    nickname=nicknamee.get()
    ccc=crosschat.CrossChat(nickname,roomid)
    ccc.on_message += [message_got]
    u.pack(fill='both',expand=True)
    threading.Thread(target = ccc.run).start()
lx.funcs["cleanover"] = cleanover
lx.funcs["login"] = login
with open('loadin.xml',mode='r',encoding='utf-8') as f:
    xml=f.read()
lx.loadxml(xml)
#out
roomide = lx.tags["roomide"][0]#entry
nicknamee = lx.tags["nicknamee"][0]#entry


root.mainloop()

结语

现在已经完成了一个简单的CC客户端,其它功能可以通过CC提供的API实现。

🔆tkinter创新🔆

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/447275.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

随机蛙跳算法 (SFLA)简单实现(Matlab代码实现)

目录 &#x1f4a5;1 概述 &#x1f4da;2 运行结果 &#x1f389;3 参考文献 &#x1f468;‍&#x1f4bb;4 Matlab代码 &#x1f4a5;1 概述 随着计算机科学与技术的迅速发展,人类生存空间的扩大以及认识与改造世界范围的拓宽,人们对科学技术提出了新的和更高的要求,其…

android中线程池的选择

线程池是把一个或多个线程通过统一的方式进行调度和重复使用的技术。 避免了因为线程过多而带来使用上的开销。 在安卓开发中&#xff0c;为了更好的性能体验&#xff0c;我们在选择线程池的时候&#xff0c;需要从具体需求来考虑&#xff0c;主要考虑以下几方面&#xff1a; …

计算机类专业的普通校招生毕业如何“卷”一份好工作?

毕业差不多两年的校招生有感 一、为什么写这篇文章&#xff1f;二、我 → 一名普通的校招生前身三、我 → 一名普通的校招生养成四、校招如何拿到offer&#xff1f;五、总结 一、为什么写这篇文章&#xff1f; 一开始我写CSDN是为了记录自己学习技术的小日记&#xff0c;小总结…

JavaScript运算符与表达式

目录 一、 二、|| 三、??与?. ?? ?. 四、... 五、[] {} [] {} 一、 严格相等运算符&#xff0c;用作逻辑判断 1 1 // 返回 true 1 1 // 返回 true&#xff0c;会先将右侧的字符串转为数字&#xff0c;再做比较 1 1 // 返回 false&#xff0c;类型不等…

每日学术速递4.22

CV - 计算机视觉 | ML - 机器学习 | RL - 强化学习 | NLP 自然语言处理 Subjects: cs.CV 1.Reference-based Image Composition with Sketch via Structure-aware Diffusion Model 标题&#xff1a;通过结构感知扩散模型与草图进行基于参考的图像合成 作者&#xff1a;Kang…

PDF转PPT:省时省力的高效方式

PDF和PPT是日常工作和学习中常见的文件格式&#xff0c;但是它们的使用场景不同&#xff0c;很多时候需要将PDF文件转换为PPT文件才能更好地展示内容。本文将介绍如何使用PDF转PPT工具来实现快速转换&#xff0c;省时省力。 一、为什么需要将PDF文件转换为PPT文件 1.PPT文件更…

English Learning - L2-15 英音地道语音语调 语调四步法 2023.04.17 周一

English Learning - L2-15 英音地道语音语调 语调 2023.04.17 周一 语调概念和汉语拼音对比 语音语调四步法语调练习意群划分重音重中之重语调的选择 语调的含义 语调概念 广义&#xff1a;语音技巧&#xff0c;连读&#xff0c;失去爆破&#xff0c;音同化&#xff0c;还有平…

如何利用AI技术实现高品质的文字转语音效果

人们越来越依赖语音技术进行交流和获取信息。语音技术可以提高工作效率和舒适度&#xff0c;减轻眼睛疲劳和阅读负担。在数字化时代&#xff0c;AI技术已经能够帮助我们实现高品质的文字转语音效果。下面我们将介绍一些方法&#xff0c;以帮助您更好地利用AI技术实现高品质的文…

Vue.js过滤器filters

目录 一、局部过滤器 二、全局过滤器 三、过滤器串联 四、过滤器接收多个参数 Vue.js允许自定义过滤器&#xff0c;过滤器的作用可被用于一些常见的文本格式化&#xff08;也就是修饰文本&#xff0c;但是文本内容不会改变&#xff09; 过滤器可以用在两个地方&#xff1a…

微信小程序开发详细步骤是什么?

微信小程序开发只需要三步&#xff0c;分别是注册小程序&#xff0c;编辑设计小程序内容和一键发布小程序zlzwgz0127。 这篇回答不介绍写代码开发小程序&#xff0c;因为更多人是不懂代码的&#xff0c;所以推荐用第三方平台开发小程序zlzwgz0127。 在开始制作小程序之前&#…

Linux基础—深入理解Linux文件系统

Linux基础—深入理解Linux文件系统与日志分析 一、inode 与 block详解1.inode 和 block 概述2.inode的内容3.inode的大小4.inode的特殊作用5.inode 的号码6.查看文件的inode 号码7.inode 耗尽故障处理 二、恢复误删除的文件1.案例&#xff1a;恢复EXT类型的文件2.案例&#xff…

qt中信号和槽机制

文章目录 信号与槽机制实现 点击按钮 关闭窗口的案例 自定义信号槽自定义信号自定义槽函数触发自定义的信号案例:请老师吃饭 断开信号当槽函数遇到重载的时候拓展 信号与槽机制 connect&#xff08;信号的发送者&#xff0c; 发送的具体信号&#xff0c;信号的接受者&#xff0…

SpringAop详解汇总

文章目录 近期想法什么是AOPSpringAOP与AspectjSpringAOP体系概述概念详解连接点- Jointpoint切入点- Pointcut通知- Advice切面- Aspect织入- Weaving 实现原理—动态代理JDK动态代理描述原理代码示例注意执行结果 优点缺点 CGLib动态代理描述原理代码示例注意执行结果 优点缺…

【UITableViewCell单元格重用补充 Objective-C语言】

一、咱们再把刚才说的UITableViewCell单元格重用的思路再给大家捋一下 1.咱们刚才说的这个单元格重用就是,当我们滚动的时候,这里给大家简单画一下, 2.就是滚动的时候,当把这个最上面的单元格滚完毕以后,把这个单元格放到缓存池里面, 3.给这个单元格要起一个ID,给它做一…

阿里云部署Stable Diffusion

系列文章目录 本地部署Stable Diffusion教程&#xff0c;亲测可以安装成功 Stable Diffusion界面参数及模型使用 谷歌Colab云端部署Stable Diffusion 进行绘图 文章目录 系列文章目录前言一、AIGC是什么&#xff1f;二、操作步骤1.资源准备-零元开通试用套餐2.创建应用3.输入…

使用matlab基于神经网络进行光束选择

一、前言 此示例说明如何使用神经网络来减少光束选择任务中的开销。在此示例中&#xff0c;您仅使用接收方的位置&#xff0c;而不是通信信道的知识。您可以通过在选定的波束对中进行搜索来减少波束扫掠开销&#xff0c;而不是对所有波束对进行详尽的波束搜索K光束对。考虑到一…

R语言ggplot2 | 修改ggplot主题

&#x1f4cb;文章目录 图形设置&#xff08;settings&#xff09;面板设置和背景&#xff08;Panel&Background&#xff09;坐标轴设置&#xff08;Axis&#xff09;标题和标签&#xff08;Title&label&#xff09;图例&#xff08;Legend&#xff09;副标题和图注&am…

静态和动态NAT,NAPT配置简介

一.类型介绍 二.功能 1.将大量的私有地址转换为公有地址(节约IP地址) 2.将一个IP地址转换为另一个IP地址(增加内部网络设备的安全性) 三.缺陷&#xff1a; 1.很消耗网络设备资源 2.破坏数据端到端传输&#xff0c;安全策略实施受限 四.配置命令 1.静态模式&#xff08;…

押注零知识证明赛道,Conflux与ACCSEAL达成战略合作

Conflux与新兴零知识证明加速芯片制造公司ACCSEAL宣布达成战略合作&#xff0c;携手共同布局零知识证明&#xff08;Zero-Knowledge Proof&#xff0c;简称ZKP&#xff09;赛道&#xff0c;探索可应用于Conflux生态系统的最先进零知识证明技术和解决方案。早在2022年3月&#x…

白话文讲计算机视觉-第九讲-霍夫变换之直线检测

霍夫变换是1962年由霍夫发明的一种检测图像中直线、圆等形状的方法。后来1972年经过Richard O. Duda和Peter E. Hart改进&#xff0c;形成了今天的霍夫变换算法。 今天我就带大家了解了解霍夫变换之直线检测是怎么特么的一回事。 1.霍夫变换 说到霍夫变换&#xff0c;首先就得…