Python is a versatile programming language that is widely used for a variety of tasks, including creating chat applications. One way I created a chat application in Python is by using the built-in socket library to handle the communication between clients and the server. While this approach is functional, the user interface for such an application can be quite basic, making it difficult for me to navigate and interact with the chat. You can still check the original post here(Python A Simple Chat Script).
To improve the user experience, I can upgrade my chat application to utilize a PyQt6 user interface. PyQt6 is a library that provides a set of Python bindings for the Qt libraries, which are widely used for creating graphical user interfaces (GUIs). By using PyQt6, I can create a more user-friendly and visually appealing interface for my chat application. But like many of my Python scripts, recieving of messages is unpredictable that is why it is constantly monitoring for new incoming messages. This is why I need to include the multithreading library so that the whole application will not freeze while waiting for the arrival of new messages.
Another useful feature that I can add to my chat application is a notification message that appears in the notification tray. This can help to alert me when a new message is received, even when the application is not in focus. To achieve this, I can use the QStyledItemDelegate class from the PyQt6.QtWidgets module. This class allows me to create a toast notification that appears in the notification tray telling me that a new message has arrived.
In summary, upgrading my Python socket chat application to utilize a PyQt6 user interface with multithreading and a notification message in the notification tray using QStyledItemDelegate can greatly improve the user experience. By using PyQt6, I can create a visually appealing and user-friendly interface, and by using multithreading, I can ensure that the application remains responsive, even when handling a large number of messages or connections. Additionally, the notification message in the notification tray using QStyledItemDelegate can alert me to new messages, even when the application is not in focus.
Here is the sample screenshot:
Please do note that this simple chat only allows communications within the same pc unlike the old version which can allow communication between 2 pc's on the same LAN but can be easily modified to make it communicate with any pc connected to the internet. I also included a combo box to allow a user to connect as a server or as a client.
Also in the works as a spoiler, I am planning to create a more feature rich chat application. I already created a new gui for this but its has a very long way to go. Here is the gui on the drawing board:
The user interface can allow users to add friends, rooms very much like yahoo messenger, facebook messaging, microsoft teams, among others. And as time goes on, I may add more features like adding user time line, synchronize their timelines to twitter, facebook and linkedin, and perhaps a marketplace, the possibilities are endless.
Here is the code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 | import sys from PyQt6.QtCore import * from PyQt6.QtGui import * from PyQt6.QtWidgets import * import mysql.connector as mysql import warnings warnings.filterwarnings('ignore') import os import socket import multiprocessing as mp import time import winrt.windows.ui.notifications as notifications import winrt.windows.data.xml.dom as dom s = socket.socket() breaker = 0 combo = '' files = '' conn = '' class Delegate(QStyledItemDelegate): def createEditor(self, parent, option, index): if index.data() == "100": return super(Delegate, self).createEditor(parent, option, index) class Window(QMainWindow): def __init__(self): super(Window, self).__init__() self.initUI() def initUI(self): widget = QWidget() self.setCentralWidget(widget) self.combo_box = QComboBox(self) self.combo_box.addItem("Server") self.combo_box.addItem("Client") self.conn_button = QPushButton("Connect") #print(dir(self.conn_button)) self.conn_button.setFixedWidth(100) self.conn_button.clicked.connect(self.connect_exec) self.text_edit = QTextEdit() self.text_edit.setReadOnly(True) self.line_edit = QLineEdit() self.line_edit.setPlaceholderText("Enter message here") self.send_button = QPushButton("Send") self.send_button.clicked.connect(self.send_message) h_layout_conn = QHBoxLayout() h_layout_conn.addWidget(self.combo_box) h_layout_conn.addWidget(self.conn_button) # Layout layout = QVBoxLayout() layout.addLayout(h_layout_conn) layout.addWidget(self.text_edit) h_layout = QHBoxLayout() h_layout.addWidget(self.line_edit) h_layout.addWidget(self.send_button) layout.addLayout(h_layout) widget = QWidget() widget.setLayout(layout) self.setCentralWidget(widget) self.setGeometry(25, 45, 350, 400) self.setWindowTitle('Pop Chat') timer = QTimer(self) timer.timeout.connect(self.showtext) timer.start(1000) self.thread() self.show() def showtext(self): global files if files != '': self.text_edit.append(files) self.notif() files = '' def send_message(self): global s, conn, combo message = self.line_edit.text() if message: self.text_edit.append(message) self.line_edit.clear() if combo == 'Server': conn.send(message.encode()) else: s.send(message.encode()) def connect_exec(self): global s, combo, conn message = "connected as " + self.combo_box.currentText() + " ..." combo = self.combo_box.currentText() if self.combo_box.currentText() == 'Server': host=socket.gethostname() port=9090 s.bind(('0.0.0.0',port)) if message: self.text_edit.append(message) self.worker = WorkerThread() self.worker.start() def notif(self): app = '{1AC14E77-02E7-4E5D-B744-2EB1AE5198B7}\\WindowsPowerShell\\v1.0\\powershell.exe' nManager = notifications.ToastNotificationManager notifier = nManager.create_toast_notifier(app) zmail = "You've Got New Message!" tString = """ <toast> <visual> <binding template='ToastGeneric'> <text>""" + zmail + """</text> </binding> </visual> <actions> <action content="Delete" arguments="action=delete"/> <action content="Dismiss" arguments="action=dismiss"/> </actions> </toast> """ #print(tString) xDoc = dom.XmlDocument() xDoc.load_xml(tString) notifier.show(notifications.ToastNotification(xDoc)) class WorkerThread(QThread): def run(self): global s, combo, files, conn if combo == 'Server': s.listen(1) conn,addr = s.accept() else: host=socket.gethostname() s.connect((host,9090)) while 1: if combo == 'Server': file = conn.recv(5000) else: file = s.recv(5000) file = file.decode() files = file def main(): app = QApplication(sys.argv) ex = Window() ex.show() sys.exit(app.exec()) if __name__ == '__main__': main() |
No comments:
Post a Comment