#python #python_3x #pyqt5 #pyqt
Есть такой код, для простоты лишнее не привожу. После авторизации срабатывает метод getChat и выводится виджет с сообщениями, которые берутся из базы. В другом потоке отправляются запросы на сервер каждую секунду и в консоли вижу, что нужный словарь с данными при отправке нового сообщения как и нужно обновляется и возвращается в переменной rs. Далее пытаюсь перерисовать виджет с сообщениями, наверное это нужно делать в методе on_request, но не получается. Прошу подсказать, ума не приложу, как это реализовать. from PyQt5 import QtCore, QtWidgets, QtGui from PyQt5.QtCore import QThread import requests import json import time colors = ['#1f3a93', '#26a65b'] class ThreadClass(QThread): about_response = QtCore.pyqtSignal(object) def __init__(self, url: str): super().__init__() self.url = url def run(self): while True: try: rs = requests.post(self.url) self.about_response.emit(rs) except Exception as e: print('Error:', e) finally: time.sleep(3) class MyWindow(QtWidgets.QWidget): def __init__(self, parent=None): QtWidgets.QWidget.__init__(self, parent) self.url_base = 'http://127.0.0.1:5000/' self.main_id = 0 self.res_usr = {} self.chat_obj = QtWidgets.QListWidget url = self.url_base + 'blog/chat' self.thread_class = ThreadClass(url) self.thread_class.about_response.connect(self.on_response) self.thread_class.start() self.title = QtWidgets.QLabel('Авторизация') self.title.setAlignment(QtCore.Qt.AlignHCenter) self.username = QtWidgets.QLineEdit() self.username.setPlaceholderText('Введите логин:') self.password = QtWidgets.QLineEdit() self.password.setPlaceholderText('Введите пароль:'), self.password.setEchoMode(QtWidgets.QLineEdit.Password) self.btnLogin = QtWidgets.QPushButton("&OK") self.lnkReg = QtWidgets.QPushButton('&Регистрация') self.vbox = QtWidgets.QVBoxLayout() self.vbox.addWidget(self.title) self.vbox.addWidget(self.username) self.vbox.addWidget(self.password) self.vbox.addWidget(self.btnLogin) self.vbox.addWidget(self.lnkReg) self.setLayout(self.vbox) self.btnLogin.clicked.connect(self.authorisation) self.lnkReg.clicked.connect(self.switchToRegistration) def on_response(self, rs): res_u = rs.text res_pst = json.loads(res_u) print(res_pst) self.chat_obj = QtWidgets.QListWidget(self) for key, value in res_pst.items(): item = QtWidgets.QListWidgetItem(self.chat_obj) item.setText(value[0] + ': ' + value[1]) if value[2] == self.main_id: item.setTextAlignment(QtCore.Qt.AlignRight) item.setForeground(QtGui.QColor(colors[0])) else: item.setTextAlignment(QtCore.Qt.AlignLeft) item.setForeground(QtGui.QColor(colors[1])) self.chat_obj.addItem(value[0] + ': ' + value[1]) self.chat_obj.repaint() def switchToRegistration(self): """ Переключение на регистрацию """ window.resize(300, 200) self.clearLayout(self.vbox) self.title = QtWidgets.QLabel('Регистрация') self.title.setAlignment(QtCore.Qt.AlignHCenter) self.username = QtWidgets.QLineEdit() self.username.setPlaceholderText('Введите логин:') self.password = QtWidgets.QLineEdit() self.password.setPlaceholderText('Введите пароль:'), self.password.setEchoMode(QtWidgets.QLineEdit.Password) self.btnReg = QtWidgets.QPushButton("&OK") self.lnkAutor = QtWidgets.QPushButton('&Авторизация') self.vbox.addWidget(self.title) self.vbox.addWidget(self.username) self.vbox.addWidget(self.password) self.vbox.addWidget(self.btnReg) self.vbox.addWidget(self.lnkAutor) self.setLayout(self.vbox) self.btnReg.clicked.connect(self.registration) self.lnkAutor.clicked.connect(self.switchToAuthorisation) def switchToAuthorisation(self): """ Переключение на авторизацию """ window.resize(300, 200) self.clearLayout(self.vbox) self.title = QtWidgets.QLabel('Авторизация') self.title.setAlignment(QtCore.Qt.AlignHCenter) self.username = QtWidgets.QLineEdit() self.username.setPlaceholderText('Введите логин:') self.password = QtWidgets.QLineEdit() self.password.setPlaceholderText('Введите пароль:'), self.password.setEchoMode(QtWidgets.QLineEdit.Password) self.btnAutor = QtWidgets.QPushButton("&OK") self.lnkReg = QtWidgets.QPushButton('&Регистрация') self.vbox.addWidget(self.title) self.vbox.addWidget(self.username) self.vbox.addWidget(self.password) self.vbox.addWidget(self.btnLogin) self.vbox.addWidget(self.lnkReg) self.setLayout(self.vbox) self.btnAutor.clicked.connect(self.authorisation) self.lnkReg.clicked.connect(self.switchToRegistration) def authorisation(self): """ Авторизация """ url = self.url_base + 'auth/login' data = {'username': self.username.text(), 'password': self.password.text()} r = requests.post(url, json=data) res_u = r.text #print(res_u) res_usr = json.loads(res_u) #print(res_usr['status']) if res_usr['status'] == 'ok': self.main_id = res_usr['id'] #print(self.main_id) self.getChat() elif res_usr['status'] == 'no': self.showError(res_usr) def registration(self): """ Регистрация """ url = self.url_base + 'auth/register' data = {'username': self.username.text(), 'password': self.password.text()} r = requests.post(url, json=data) res_u = r.text #print(res_u) res_usr = json.loads(res_u) if res_usr['status'] == 'ok': self.switchToAuthorisation() elif res_usr['status'] == 'no': self.showError(res_usr) def clearLayout(self, layout): """ Очистка окошка """ for i in reversed(range(layout.count())): layout.itemAt(i).widget().setParent(None) def showError(self, res_usr): """ Показать ошибки """ self.label = QtWidgets.QLabel(res_usr['error']) self.label.setAlignment(QtCore.Qt.AlignHCenter) self.vbox.addWidget(self.label) def showSuccess(self, res_usr): """ Показать успех """ self.label = QtWidgets.QLabel(res_usr['success_msg']) self.label.setAlignment(QtCore.Qt.AlignHCenter) self.vbox.addWidget(self.label) def getChat(self): window.resize(300, 400) self.clearLayout(self.vbox) self.label = QtWidgets.QLabel('Чат') self.label.setAlignment(QtCore.Qt.AlignHCenter) self.vbox.addWidget(self.label) url = self.url_base + 'blog/chat' r = requests.post(url) print(r.status_code, r.reason) print(r.request.headers) res_u = r.text res_pst = json.loads(res_u) #print(res_pst) self.chat_obj = QtWidgets.QListWidget(self) for key, value in res_pst.items(): item = QtWidgets.QListWidgetItem(self.chat_obj) item.setText(value[0] + ': ' + value[1]) if value[2] == self.main_id: item.setTextAlignment(QtCore.Qt.AlignRight) item.setForeground(QtGui.QColor(colors[0])) else: item.setTextAlignment(QtCore.Qt.AlignLeft) item.setForeground(QtGui.QColor(colors[1])) #self.chat_obj.addItem(value[0] + ': ' + value[1]) self.vbox.addWidget(self.chat_obj) self.message = QtWidgets.QLineEdit() self.message.setPlaceholderText('Введите сообщение') self.vbox.addWidget(self.message) self.btnSend = QtWidgets.QPushButton("&Отправить") self.vbox.addWidget(self.btnSend) self.btnSend.clicked.connect(self.sendmessage) def sendmessage(self): """ Отправка сообщения """ print(self.main_id) url = self.url_base + 'blog/create/{}'.format(self.main_id) data = {'message': self.message.text()} #print(data) r = requests.post(url, json=data) #print(r.status_code, r.reason) #print(r.request.headers) res_m = r.text #print(res_m) res_usr = json.loads(res_m) if res_usr['status'] == 'ok': self.showSuccess(res_usr) elif res_usr['status'] == 'no': self.showError(res_usr) self.message.clear() if __name__ == "__main__": import sys app = QtWidgets.QApplication(sys.argv) window = MyWindow() window.setWindowTitle("Простой Мессенжер") window.resize(300, 200) window.show() sys.exit(app.exec_()) Вот код серверной части, тот, который отвечает за формирование чата: from flask import ( Blueprint, flash, g, redirect, render_template, request, url_for ) from werkzeug.exceptions import abort from flaskr.auth import login_required from flaskr.db import get_db import json bp = Blueprint('blog', __name__, url_prefix='/blog') @bp.route('/chat', methods=('GET', 'POST')) def chat(): db = get_db() posts = db.execute( 'SELECT p.id, author_id, msg, created, u.username' ' FROM post p JOIN user u' ' ON u.id = p.author_id' ' ORDER BY p.created DESC', ).fetchall() pst = {} for i in posts: pst[i['id']] = [i['username'], i['msg'], i['author_id']] dc = pst dc = json.dumps(dc) return dc @bp.route('/create/', methods=('GET', 'POST')) def create(main_id): if request.method == 'POST': msg = request.get_json().get('message') error = None if not msg: error = 'Message is required.' if error is not None: dc = {'error': error, 'status': 'not'} dc = json.dumps(dc) return dc else: db = get_db() author_id = main_id db.execute( 'INSERT INTO post (msg, author_id)' ' VALUES (?, ?)', (msg, author_id) ) db.commit() dc = {'success_msg': 'The message successfully sent', 'status': 'ok'} dc = json.dumps(dc) return dc return dc
Ответы
Ответ 1
Мои изменения рядом с # TODO:. Главное что сделал -- убрал пересоздание виджета-списка и манипуляции с layout (это можно потом сделать, сейчас это будет мешать) class MyWindow(QtWidgets.QWidget): def __init__(self, parent=None): super().__init__(parent) self.url_base = 'http://127.0.0.1:5000/' self.main_id = 0 self.res_usr = dict() # TODO: # self.chat_obj = QtWidgets.QListWidget url = self.url_base + 'blog/chat' self.thread_class = ThreadClass(url) self.thread_class.about_response.connect(self.on_response) self.thread_class.start() self.title = QtWidgets.QLabel('Авторизация') self.title.setAlignment(QtCore.Qt.AlignHCenter) self.username = QtWidgets.QLineEdit() self.username.setPlaceholderText('Введите логин:') self.password = QtWidgets.QLineEdit() self.password.setPlaceholderText('Введите пароль:'), self.password.setEchoMode(QtWidgets.QLineEdit.Password) self.btnLogin = QtWidgets.QPushButton("&OK") self.lnkReg = QtWidgets.QPushButton('&Регистрация') self.chat_obj = QtWidgets.QListWidget() self.vbox = QtWidgets.QVBoxLayout() self.vbox.addWidget(self.title) self.vbox.addWidget(self.username) self.vbox.addWidget(self.password) self.vbox.addWidget(self.btnLogin) self.vbox.addWidget(self.lnkReg) # TODO: # Пусть пока будет self.vbox.addWidget(self.chat_obj) self.setLayout(self.vbox) self.btnLogin.clicked.connect(self.authorisation) self.lnkReg.clicked.connect(self.switchToRegistration) def on_response(self, rs): # TODO: res_pst = rs.json() # res_u = rs.text # res_pst = json.loads(res_u) print(res_pst) for key, value in res_pst.items(): item = QtWidgets.QListWidgetItem(self.chat_obj) item.setText(value[0] + ': ' + value[1]) if value[2] == self.main_id: item.setTextAlignment(QtCore.Qt.AlignRight) item.setForeground(QtGui.QColor(colors[0])) else: item.setTextAlignment(QtCore.Qt.AlignLeft) item.setForeground(QtGui.QColor(colors[1])) self.chat_obj.addItem(value[0] + ': ' + value[1]) def switchToRegistration(self): """ Переключение на регистрацию """ # TODO: self.resize(300, 200) # self.clearLayout(self.vbox) self.title = QtWidgets.QLabel('Регистрация') self.title.setAlignment(QtCore.Qt.AlignHCenter) self.username = QtWidgets.QLineEdit() self.username.setPlaceholderText('Введите логин:') self.password = QtWidgets.QLineEdit() self.password.setPlaceholderText('Введите пароль:'), self.password.setEchoMode(QtWidgets.QLineEdit.Password) self.btnReg = QtWidgets.QPushButton("&OK") self.lnkAutor = QtWidgets.QPushButton('&Авторизация') self.vbox.addWidget(self.title) self.vbox.addWidget(self.username) self.vbox.addWidget(self.password) self.vbox.addWidget(self.btnReg) self.vbox.addWidget(self.lnkAutor) self.setLayout(self.vbox) self.btnReg.clicked.connect(self.registration) self.lnkAutor.clicked.connect(self.switchToAuthorisation) def switchToAuthorisation(self): """ Переключение на авторизацию """ # TODO: self.resize(300, 200) # self.clearLayout(self.vbox) self.title = QtWidgets.QLabel('Авторизация') self.title.setAlignment(QtCore.Qt.AlignHCenter) self.username = QtWidgets.QLineEdit() self.username.setPlaceholderText('Введите логин:') self.password = QtWidgets.QLineEdit() self.password.setPlaceholderText('Введите пароль:'), self.password.setEchoMode(QtWidgets.QLineEdit.Password) self.btnAutor = QtWidgets.QPushButton("&OK") self.lnkReg = QtWidgets.QPushButton('&Регистрация') self.vbox.addWidget(self.title) self.vbox.addWidget(self.username) self.vbox.addWidget(self.password) self.vbox.addWidget(self.btnLogin) self.vbox.addWidget(self.lnkReg) self.setLayout(self.vbox) self.btnAutor.clicked.connect(self.authorisation) self.lnkReg.clicked.connect(self.switchToRegistration) def authorisation(self): """ Авторизация """ url = self.url_base + 'auth/login' data = {'username': self.username.text(), 'password': self.password.text()} r = requests.post(url, json=data) # TODO: res_usr = r.json() # res_u = r.text # #print(res_u) # res_usr = json.loads(res_u) #print(res_usr['status']) if res_usr['status'] == 'ok': self.main_id = res_usr['id'] #print(self.main_id) self.getChat() elif res_usr['status'] == 'no': self.showError(res_usr) def registration(self): """ Регистрация """ url = self.url_base + 'auth/register' data = {'username': self.username.text(), 'password': self.password.text()} r = requests.post(url, json=data) res_usr = r.json() # TODO: # res_u = r.text # #print(res_u) # res_usr = json.loads(res_u) if res_usr['status'] == 'ok': self.switchToAuthorisation() elif res_usr['status'] == 'no': self.showError(res_usr) # TODO: # def clearLayout(self, layout): # """ # Очистка окошка # """ # for i in reversed(range(layout.count())): # layout.itemAt(i).widget().setParent(None) def showError(self, res_usr): """ Показать ошибки """ self.label = QtWidgets.QLabel(res_usr['error']) self.label.setAlignment(QtCore.Qt.AlignHCenter) self.vbox.addWidget(self.label) def showSuccess(self, res_usr): """ Показать успех """ self.label = QtWidgets.QLabel(res_usr['success_msg']) self.label.setAlignment(QtCore.Qt.AlignHCenter) self.vbox.addWidget(self.label) def getChat(self): window.resize(300, 400) # self.clearLayout(self.vbox) self.label = QtWidgets.QLabel('Чат') self.label.setAlignment(QtCore.Qt.AlignHCenter) self.vbox.addWidget(self.label) url = self.url_base + 'blog/chat' r = requests.post(url) print(r.status_code, r.reason) print(r.request.headers) # TODO: res_pst = r.json() # res_u = r.text # res_pst = json.loads(res_u) #print(res_pst) # self.chat_obj = QtWidgets.QListWidget(self) for key, value in res_pst.items(): item = QtWidgets.QListWidgetItem(self.chat_obj) item.setText(value[0] + ': ' + value[1]) if value[2] == self.main_id: item.setTextAlignment(QtCore.Qt.AlignRight) item.setForeground(QtGui.QColor(colors[0])) else: item.setTextAlignment(QtCore.Qt.AlignLeft) item.setForeground(QtGui.QColor(colors[1])) #self.chat_obj.addItem(value[0] + ': ' + value[1]) # TODO: в конструкторе добавлено на форму # self.vbox.addWidget(self.chat_obj) self.message = QtWidgets.QLineEdit() self.message.setPlaceholderText('Введите сообщение') self.vbox.addWidget(self.message) self.btnSend = QtWidgets.QPushButton("&Отправить") self.vbox.addWidget(self.btnSend) self.btnSend.clicked.connect(self.sendmessage) def sendmessage(self): """ Отправка сообщения """ print(self.main_id) url = self.url_base + 'blog/create/{}'.format(self.main_id) data = {'message': self.message.text()} #print(data) r = requests.post(url, json=data) #print(r.status_code, r.reason) #print(r.request.headers) # TODO: res_usr = r.json() # res_m = r.text # #print(res_m) # res_usr = json.loads(res_m) if res_usr['status'] == 'ok': self.showSuccess(res_usr) elif res_usr['status'] == 'no': self.showError(res_usr) self.message.clear() Код с self.label = явно костыльный, но его не трогал, т.к. проблема с QListWidget, а не с этим
Комментариев нет:
Отправить комментарий