|
| 1 | +# This is a Qt terminal program |
| 2 | + |
| 3 | + |
| 4 | +from PySide6.QtWidgets import QTextEdit, QApplication, QMainWindow |
| 5 | +from PySide6.QtCore import Slot |
| 6 | +import sys |
| 7 | +from tcpip import TCPClient |
| 8 | +from controls import * |
| 9 | + |
| 10 | +############################################################### |
| 11 | + |
| 12 | +term_title = 'Qt Python simple TCP client' |
| 13 | + |
| 14 | +win_min_height = 500 |
| 15 | +win_min_width = 600 |
| 16 | + |
| 17 | +term_min_width = 300 |
| 18 | + |
| 19 | +# Names of notebook's tables |
| 20 | +tab1Name = 'Basic' |
| 21 | +tab2Name = 'Edit' |
| 22 | + |
| 23 | +def_btn_fg_color = 'black' |
| 24 | +def_btn_bg_color = '#eeeeee' |
| 25 | +btn_font_family = 'Titillium' |
| 26 | +btn_font_size = '12px' |
| 27 | + |
| 28 | +cmd_end = b'\r' |
| 29 | + |
| 30 | +############################################################### |
| 31 | + |
| 32 | +# Tab button [0,1,2,3]: |
| 33 | +# 0 - label of the button |
| 34 | +# 1 - command to send |
| 35 | +# 2 - foreground color |
| 36 | +# 3 - background color |
| 37 | + |
| 38 | +# --------------- TAB1 BUTTONS --------------- |
| 39 | +T1_0 = [['00000', '00000', '', '#66ccff'], |
| 40 | + ['11111', '11111', '', '#66ccff'], |
| 41 | + ['22222', '22222', '', '#66ccff'], |
| 42 | + ['33333', '33333', '', '#66ccff'], |
| 43 | + ['44444', '44444', '', '#66ccff'], |
| 44 | + ['55555', '55555', '', '#66ccff'], |
| 45 | + ['6' * 5, '6' * 5, '', '#66ccff'], |
| 46 | + ['7' * 5, '7' * 5, '', ''], |
| 47 | + ['8' * 5, '8' * 5, '', ''], |
| 48 | + ['9' * 5, '9' * 5, '', ''], |
| 49 | + ['', '', '', ''], |
| 50 | + ['', '', '', '']] |
| 51 | + |
| 52 | +T1_1 = [['abcdef', 'abcdef', '', '#ffbf00'], |
| 53 | + ['-------', '-------', '', '#ffbf00'], |
| 54 | + ['hello!', 'hello!', '', '#ffbf00'], |
| 55 | + ['hi!', 'hi!', '', '#ffbf00'], |
| 56 | + ['!!!!!!!!!!', '!!!!!!!!!!', '', '#ffbf00'], |
| 57 | + ['', '', '', ''], |
| 58 | + ['', '', '', '']] |
| 59 | + |
| 60 | +T1_2 = [['a' * 10, 'a' * 10, '', '#ffbf00'], |
| 61 | + ['b' * 10, 'b' * 10, '', '#ffbf00'], |
| 62 | + ['c' * 10, 'c' * 10, '', '#ffbf00'], |
| 63 | + ['d' * 10, 'd' * 10, '', '#ffbf00'], |
| 64 | + ['e' * 10, 'e' * 10, '', '#ffbf00'], |
| 65 | + ['', '', '', ''], |
| 66 | + ['', '', '', '']] |
| 67 | + |
| 68 | +T1 = [T1_0, T1_1, T1_2] |
| 69 | + |
| 70 | + |
| 71 | +# --------------- TAB2 BUTTONS --------------- |
| 72 | +T2 = ['1'*10, '2'*10, '3'*10, '4'*10, '5'*10, '6'*10, '7'*10, '8'*10, '9'*10, '0'*10] |
| 73 | + |
| 74 | + |
| 75 | +class MainWindow(QMainWindow): |
| 76 | + def __init__(self): |
| 77 | + super().__init__() |
| 78 | + self.setWindowTitle(term_title) |
| 79 | + self.statusBar().showMessage('Welcome!') |
| 80 | + # central widget |
| 81 | + central_widget = QWidget() |
| 82 | + self.setCentralWidget(central_widget) |
| 83 | + hbox = QHBoxLayout(central_widget) |
| 84 | + vbox1 = QVBoxLayout() |
| 85 | + # create term |
| 86 | + self.term = QTextEdit() |
| 87 | + self.term.setReadOnly(True) |
| 88 | + self.term.setMinimumWidth(term_min_width) |
| 89 | + self.term.setStyleSheet(""" |
| 90 | + background-color: #101010; |
| 91 | + color: #FFFFFF; |
| 92 | + font-family: Titillium; |
| 93 | + font-size: 12px; |
| 94 | + """) |
| 95 | + vbox1.addWidget(self.term) |
| 96 | + # clear term button |
| 97 | + self.clear_term_btn = QPushButton('Clear terminal') |
| 98 | + self.clear_term_btn.setStyleSheet('background-color: #101010; color: #ffffff;') |
| 99 | + vbox1.addWidget(self.clear_term_btn) |
| 100 | + hbox.addLayout(vbox1) |
| 101 | + self.clear_term_btn.clicked.connect(self.clear_term) |
| 102 | + # create side panel |
| 103 | + self.side_panel = QWidget() |
| 104 | + vbox2 = QVBoxLayout(self.side_panel) |
| 105 | + # add side panel to main window |
| 106 | + hbox.addWidget(self.side_panel) |
| 107 | + # create tcp client and bind handlers |
| 108 | + self.tcp_client = TCPClient() |
| 109 | + self.tcp_client.sock.readyRead.connect(self.on_port_rx) |
| 110 | + # create send_any_cmd |
| 111 | + self.send_any_msg = SendAny() |
| 112 | + self.send_any_msg.any_btn.clicked.connect(self.send_any) |
| 113 | + # create notebook |
| 114 | + self.notebook = Notebook() |
| 115 | + # add tables to the notebook |
| 116 | + self.notebook.add_tab_btn(tab1Name, T1, self.send) |
| 117 | + self.notebook.add_tab_edit(tab2Name, len(T2), T2, self.send_any) |
| 118 | + # add controls and notebook to side panel |
| 119 | + vbox2.addWidget(self.tcp_client) |
| 120 | + vbox2.addWidget(self.send_any_msg) |
| 121 | + vbox2.addWidget(self.notebook) |
| 122 | + |
| 123 | + def send(self, btn): |
| 124 | + if self.tcp_client.started: |
| 125 | + cmd_to_send = btn.get_cmd() |
| 126 | + if cmd_to_send and self.tcp_client.sock: |
| 127 | + if isinstance(cmd_to_send, str): # if type of cmd_to_send is a <string> |
| 128 | + self.tcp_client.sock.write(cmd_to_send.encode('ascii')) |
| 129 | + self.tcp_client.sock.write(cmd_end) |
| 130 | + |
| 131 | + def send_any(self): |
| 132 | + if self.tcp_client.started: |
| 133 | + ref = self.sender() # get object created received signal |
| 134 | + data = ref.parent().any_field.text() # get text from any_field using parent |
| 135 | + if data and self.tcp_client.sock: |
| 136 | + self.tcp_client.sock.write(data.encode('ascii')) |
| 137 | + self.tcp_client.sock.write(cmd_end) |
| 138 | + |
| 139 | + def write(self, data): |
| 140 | + if self.started: |
| 141 | + self.tcp_client.sock.write(data) |
| 142 | + |
| 143 | + def clear_term(self): |
| 144 | + self.term.clear() # clear terminal |
| 145 | + |
| 146 | + def closeEvent(self, event): |
| 147 | + self.tcp_client.stop() |
| 148 | + event.accept() |
| 149 | + |
| 150 | + @Slot() |
| 151 | + def on_port_rx(self): |
| 152 | + num_rx_bytes = self.tcp_client.sock.bytesAvailable() |
| 153 | + rx_bytes = self.tcp_client.sock.read(num_rx_bytes) |
| 154 | + data = bytes(rx_bytes).decode('ascii') |
| 155 | + try: |
| 156 | + self.term.insertPlainText(data) |
| 157 | + except Exception: |
| 158 | + self.term.insertPlainText('\r[something went wrong!]\r') |
| 159 | + self.term.ensureCursorVisible() |
| 160 | + |
| 161 | + |
| 162 | +def main(): |
| 163 | + app = QApplication([]) |
| 164 | + main_win = MainWindow() |
| 165 | + main_win.resize(win_min_width, win_min_height) |
| 166 | + main_win.show() |
| 167 | + sys.exit(app.exec()) # PySide6 |
| 168 | + # sys.exit(app.exec_()) # PySide2 |
| 169 | + |
| 170 | + |
| 171 | +if __name__ == '__main__': |
| 172 | + main() |
| 173 | + |
0 commit comments