Skip to content

Commit c6c7939

Browse files
authored
Initial
0 parents  commit c6c7939

File tree

4 files changed

+731
-0
lines changed

4 files changed

+731
-0
lines changed

controls.py

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
# Controls for terminals
2+
3+
from PySide6.QtCore import Qt
4+
from PySide6.QtWidgets import QWidget, QPushButton, QHBoxLayout, QVBoxLayout, QCheckBox
5+
from PySide6.QtWidgets import QTabWidget, QGridLayout, QButtonGroup, QLineEdit, QGroupBox
6+
7+
8+
class Controls(QGroupBox):
9+
def __init__(self):
10+
super().__init__()
11+
self.setTitle('Controls')
12+
# add layout
13+
layout = QGridLayout(self)
14+
# create buttons, etc
15+
self.time_box = QCheckBox('Add time', self)
16+
layout.addWidget(self.time_box, 0, 0)
17+
#
18+
self.echo_box = QCheckBox('Echo Tx', self)
19+
layout.addWidget(self.echo_box, 0, 1)
20+
#
21+
self.clear_btn = QPushButton('Clear term')
22+
self.clear_btn.setStyleSheet('background-color: #333333; color: #eeeeee;')
23+
layout.addWidget(self.clear_btn, 1, 0)
24+
#
25+
self.copy_btn = QPushButton('Copy from term')
26+
self.copy_btn.setStyleSheet('background-color: #999999;')
27+
layout.addWidget(self.copy_btn, 0, 2)
28+
#
29+
self.cut_btn = QPushButton('Cut from term')
30+
self.cut_btn.setStyleSheet('background-color: #999999;')
31+
layout.addWidget(self.cut_btn, 1, 2)
32+
#
33+
self.info_btn = QPushButton('Ports info')
34+
self.info_btn.setStyleSheet('background-color: #ffff00;')
35+
layout.addWidget(self.info_btn, 0, 3)
36+
#
37+
self.free_btn = QPushButton('Get free ports')
38+
self.free_btn.setStyleSheet('background-color: #ffff00;')
39+
layout.addWidget(self.free_btn, 1, 3)
40+
41+
42+
class SendAny(QWidget):
43+
def __init__(self):
44+
super().__init__()
45+
# add layout
46+
layout = QHBoxLayout(self)
47+
layout.setContentsMargins(0, 0, 0, 0)
48+
#
49+
self.any_field = QLineEdit()
50+
self.any_field.setAlignment(Qt.AlignCenter)
51+
layout.addWidget(self.any_field)
52+
#
53+
self.any_btn = QPushButton('Send')
54+
self.any_btn.setStyleSheet('background-color: #ffffff;')
55+
layout.addWidget(self.any_btn)
56+
57+
58+
class NewButton(QPushButton):
59+
cmd = ''
60+
61+
def __init__(self, lbl):
62+
super().__init__()
63+
self.setText(lbl)
64+
self.setMinimumHeight(20)
65+
66+
def set_cmd(self, cmd):
67+
self.cmd = cmd
68+
69+
def get_cmd(self):
70+
return self.cmd
71+
72+
73+
class Notebook(QTabWidget):
74+
75+
def_btn_fg_color = 'black'
76+
def_btn_bg_color = '#eeeeee'
77+
btn_font_family = 'Titillium'
78+
btn_font_size = '12px'
79+
80+
def __init__(self):
81+
super().__init__()
82+
83+
# method to add Tables with buttons
84+
def add_tab_btn(self, tab_name, btn_data, handler):
85+
# create new table
86+
t1 = QWidget()
87+
self.addTab(t1, tab_name)
88+
t1_layout = QGridLayout(t1)
89+
# add buttons' group
90+
group = QButtonGroup(self)
91+
group.buttonClicked.connect(handler)
92+
c = 0 # defines number of column of buttons in the grid
93+
for col in btn_data:
94+
i = 0 # counter to define number of line of the buttons in the grid
95+
for btn in col:
96+
if btn[0]: # if future button's label is not empty
97+
b = NewButton(btn[0]) # create button object
98+
b.set_cmd(btn[1]) # set button's command
99+
group.addButton(b)
100+
t1_layout.addWidget(b, i, c)
101+
if not btn[2]: btn[2] = self.def_btn_fg_color # if fg colour is not defined use default one
102+
if not btn[3]: btn[3] = self.def_btn_bg_color # if bg colour is not defined use default one
103+
b.setStyleSheet('background-color: ' + btn[3] + '; ' +
104+
'color: ' + btn[2] + '; ' +
105+
'font-family: ' + self.btn_font_family + '; ' +
106+
'font-size: ' + self.btn_font_size + ';')
107+
i = i + 1 # next line
108+
c = c + 1 # next column
109+
110+
# method to add Tables with editable fields
111+
def add_tab_edit(self, tab_name, num_of_fields, tab_data, handler):
112+
# create new table
113+
tab = QWidget()
114+
self.addTab(tab, tab_name)
115+
layout = QVBoxLayout(tab)
116+
for each in range(num_of_fields):
117+
fld = SendAny()
118+
fld.any_btn.clicked.connect(handler)
119+
fld.any_btn.setStyleSheet('background-color: #FFB273')
120+
layout.addWidget(fld)
121+
try:
122+
fld.any_field.setText(tab_data[each])
123+
except Exception:
124+
pass
125+
126+

main.py

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
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+
38.6 KB
Loading

0 commit comments

Comments
 (0)