Я создаю приложение чата, и мне нужен класс пользовательского интерфейса, чтобы иметь доступ к классу приложения чата, чтобы класс пользовательского интерфейса мог отправлять сообщения на основе того, что введено в пользовательский интерфейс, И мне нужно, чтобы приложение чата могло получить доступ к пользовательскому интерфейсу, чтобы приложение чата могло добавлять полученные сообщения в пользовательский интерфейс.
Это может вас сильно сбить с толку, поэтому для упрощения вот ошибка и код:
< pre class="lang-bash Prettyprint-override">
Код: Выделить всё
joined chat asdassas
sfafs: as
Exception in thread Thread-2 (start_receiver):
Traceback (most recent call last):
File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.12_3.12.752.0_x64__qbz5n2kfra8p0\Lib\threading.py", line 1073, in _bootstrap_inner
self.run()
File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.12_3.12.752.0_x64__qbz5n2kfra8p0\Lib\threading.py", line 1010, in run
self._target(*self._args, **self._kwargs)
File "C:\Users\cosmi\Documents\ripper\chat_app.py", line 72, in start_receiver
self.channel.start_consuming()
File "C:\Users\cosmi\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.12_qbz5n2kfra8p0\LocalCache\local-packages\Python312\site-packages\pika\adapters\blocking_connection.py", line 1883, in start_consuming
self._process_data_events(time_limit=None)
File "C:\Users\cosmi\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.12_qbz5n2kfra8p0\LocalCache\local-packages\Python312\site-packages\pika\adapters\blocking_connection.py", line 2044, in _process_data_events
self.connection.process_data_events(time_limit=time_limit)
File "C:\Users\cosmi\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.12_qbz5n2kfra8p0\LocalCache\local-packages\Python312\site-packages\pika\adapters\blocking_connection.py", line 851, in process_data_events
self._dispatch_channel_events()
File "C:\Users\cosmi\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.12_qbz5n2kfra8p0\LocalCache\local-packages\Python312\site-packages\pika\adapters\blocking_connection.py", line 567, in _dispatch_channel_events
impl_channel._get_cookie()._dispatch_events()
File "C:\Users\cosmi\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.12_qbz5n2kfra8p0\LocalCache\local-packages\Python312\site-packages\pika\adapters\blocking_connection.py", line 1510, in _dispatch_events
consumer_info.on_message_callback(self, evt.method,
File "C:\Users\cosmi\Documents\ripper\chat_app.py", line 45, in callback
self.ack_message(ch, method, properties, body)
File "C:\Users\cosmi\Documents\ripper\chat_app.py", line 39, in ack_message
message_label = tk.Label(ui.root, text=message)
^^^^^^^
AttributeError: Объект NoneType не имеет атрибута root
Код: Выделить всё
# import libraries
import pika
import threading
import tkinter as tk # tkinter used for the gui
chat_app = None
ui = None
class ChatApp:
host = 'localhost'
port = 5672
username = 'guest'
password = 'guest'
def __init__(self, user_queue, host_queue):
# define queue variables
self.user_queue = user_queue
self.host_queue = host_queue
# create variable containing credentials to create a connection
self.credentials = pika.PlainCredentials(ChatApp.username, ChatApp.password)
# create a connection using the host and port variables and credentials defined one line before
self.connection = pika.BlockingConnection(
pika.ConnectionParameters(host=ChatApp.host, port=ChatApp.port, credentials=self.credentials)
)
# create a thread that starts the receiver
self.receiver_thread = threading.Thread(target=self.start_receiver, args=(user_queue, ))
# start this thread
self.receiver_thread.start()
def ack_message(self, channel, method, properties, body):
# this function acknowledges that we received the message
global ui
message = body.decode()
print(message)
message_label = tk.Label(ui.root, text=message)
channel.basic_ack(delivery_tag=method.delivery_tag)
def start_receiver(self, queue_name):
print(f"joined chat {self.host_queue}")
def callback(ch, method, properties, body):
self.ack_message(ch, method, properties, body)
# set credentials
credentials = self.credentials
# create connection
connection = pika.BlockingConnection(
pika.ConnectionParameters(host=ChatApp.host, port=ChatApp.port, credentials=credentials)
)
# get channel
self.channel = connection.channel()
# declare a fanout exchange to broadcast messages to all queues
self.channel.exchange_declare(exchange='chatroom', exchange_type='fanout')
# declare a unique queue for each user
result = self.channel.queue_declare(queue=queue_name, durable=True)
queue_name = result.method.queue
# bind the queue to the exchange
self.channel.queue_bind(exchange='chatroom', queue=queue_name)
# tell the consumer to run callback when a message is received
self.channel.basic_consume(queue=queue_name, on_message_callback=callback)
# start consuming
self.channel.start_consuming()
def send_message(self, message):
# get channel
channel = self.connection.channel()
# declare the fanout exchange
channel.exchange_declare(exchange='chatroom', exchange_type='fanout')
# publish the message to the exchange
channel.basic_publish(exchange='chatroom', routing_key='', body=f"{self.user_queue}: {message}")
UI класса:
# определение переменных (это постоянные переменные, их нельзя изменить)
title = "Приложение чата"
Dimensions = " 500x500"
text_box_width = 40
text_box_height = 2
def __init__(self):
# инициализировать корневое окно для tkinter
self.root = tk. Tk()
# устанавливаем заголовок, ширину и высоту
self.root.title(UI.title)
self.root.geometry(UI.dimensions)
# вызываем создайте функцию пользовательского интерфейса, определенную позже в коде
self.create_joining_ui()
# основной цикл
self.root.mainloop()
defclear_joining_ui(self):< br /> self.title.destroy()
self.username_label.destroy()
self.username_box.destroy()
self.host_room_label.destroy()
self.host_room_box .destroy()
self.join_button.destroy()
def create_joining_ui(self):
def join_button_callback():
# 1.0 говорит читать с первой строки , end-1c — это END без символа новой строки
globalchat_app
chat_app = ChatApp(self.username_box.get("1.0", "end-1c"), self.host_room_box.get("1.0", "end-1c"))
# очистите интерфейс присоединения, чтобы получить комнату ui
self.clear_joining_ui()
self.create_room_ui()
# создайте заголовок
self.title = tk.Label(self.root, text="Chat app")
self.title.pack()
# текстовые поля для включения в фактическую функцию инициализации приложения чата
# также есть метки для текстовых полей, чтобы пользователь знал, какое поле для чего предназначено.
self.username_label = tk.Label(self.root, text="Username")
self .username_label.pack()
self.username_box = tk.Text(self.root, height=UI.text_box_height, width=UI.text_box_width)
self.username_box.pack()
# поле и метка имени комнаты чата
self.host_room_label = tk.Label(self.root, text="Host room")
self.host_room_label.pack()
self.host_room_box = tk. Text(self.root, height=UI.text_box_height, width=UI.text_box_width)
self.host_room_box.pack()
# кнопка присоединения
self.join_button = tk.Button(self. root, text="Join", команда=join_button_callback)
self.join_button.pack()
def create_room_ui(self):
def send_msg_callback():
globalchat_app
# 1.0 сообщает, что нужно читать с первой строки, end-1c — это END без символа новой строки
message = self.message_box.get("1.0", "end-1c")
chat_app .send_message(message)
self.message_label = tk.Label(self.root, text="Message")
self.message_label.pack()
self.message_box = tk.Text(self.root, height=UI.text_box_height, width=UI.text_box_width)
self.message_box.pack()
self.send_msg_button = tk.Button(self.root, text=" Отправить", команда=send_msg_callback)
self.send_msg_button.pack()
def main():
global ui
ui = UI()
if __name__ == "__main__":
main()
Источник: https://stackoverflow.com/questions/781 ... -in-python