Мигающие индикаторы PyQt5
Я написал небольшой интерфейс с использованием библиотеки PyQt5. В нем есть таблица, куда поступают данные с прибора, а внизу статус панель.
При приеме или передаче каждого пакета данных с прибора, на статус панели должны мигать индикаторы Tx и Rx типа светодиода на плате. Сейчас это просто статичный текст.
Как мне реализовать это мигание зеленым и красным цветом на 30-50 мс при передаче данных?
Вопрос касается только стороны GUI, откуда брать сигнал, мне понятно. Какой виджет PyQt5 лучше использовать и каким образом?
Код статус GUI:
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
# конфигурация главного окна и центрального виджета
self.central_widget = QWidget(self)
self.setGeometry(50, 50, 1500, 800)
self.setWindowTitle('Чтение БКУ')
self.setCentralWidget(self.central_widget)
self.layout_main_window = QVBoxLayout()
self.central_widget.setLayout(self.layout_main_window)
# конфигурация верхней панели инструментов
self.btn_start_reading = QPushButton("Считать")
self.btn_start_reading.clicked.connect(self.start_read)
self.btn_save_to_file = QPushButton("Экспорт")
self.btn_save_to_file.clicked.connect(self.save_to_file)
self.layout_toolbar = QHBoxLayout()
self.layout_toolbar.addStretch(1)
self.layout_toolbar.addWidget(self.btn_start_reading)
self.layout_toolbar.addWidget(self.btn_save_to_file)
self.layout_main_window.addLayout(self.layout_toolbar)
# конфигурация таблицы
self.layout_table = QHBoxLayout()
self.table = QTableWidget()
self.table.setColumnCount(9)
self.table.setRowCount(13500)
self.table.setHorizontalHeaderLabels(['№', 'Дата и время', 'БКУ', 'КЛ', 'АУ', 'Канал', 'Код события', 'Доп. параметр', 'Описание'])
self.table.horizontalHeader().setStretchLastSection(True)
self.table.horizontalHeader().setVisible(True)
self.layout_table.addWidget(self.table)
self.layout_main_window.addLayout(self.layout_table)
# конфигурация статус панели
self.layout_status_bar = QHBoxLayout()
self.layout_status_bar.addStretch(0)
self.layout_status_bar.setDirection(QBoxLayout.RightToLeft)
self.btn_select_port = QPushButton('Выбрать порт')
self.label_tx = QLabel('Tx: ')
self.label_rx = QLabel('Rx: ')
self.label_trans_packets = QLabel('Передано: 0 ')
self.label_rec_packets = QLabel('Принято: 0 ')
self.label_count_of_log_entries = QLabel('Количество записей: 0 ')
self.label_session_time = QLabel('00:00:00')
self.layout_status_bar.addWidget(self.label_session_time)
self.layout_status_bar.addWidget(self.label_count_of_log_entries)
self.layout_status_bar.addWidget(self.label_rec_packets)
self.layout_status_bar.addWidget(self.label_trans_packets)
self.layout_status_bar.addWidget(self.label_rx)
self.layout_status_bar.addWidget(self.label_tx)
self.layout_status_bar.addWidget(self.btn_select_port)
self.layout_main_window.addLayout(self.layout_status_bar)
Так выглядит приложение. Индикаторы Tx и Rx в левом нижнем углу.
Ответы (2 шт):
Автор решения: Александр
→ Ссылка
Можно использовать QLabel
if signal:
QLabel().setStyleSheet("background-color : red;")
else:
QLabel().setStyleSheet("background-color : white;")
Автор решения: S. Nick
→ Ссылка
Как вариант, примерно так:
import sys
import random
from PyQt5 import QtCore, QtWidgets
from PyQt5.Qt import *
# +++ vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
class Thread(QtCore.QThread):
dateSignal = QtCore.pyqtSignal(str)
def __init__(self):
super().__init__()
def run(self):
while True:
# тут вы получаете какие-то данные с прибора
text = random.choice(['Tx', 'Rx'])
# тут вы испускаете сигнал и передаете какие-то данные
self.dateSignal.emit(text)
# 40 мс
self.msleep(40)
# +++ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
# конфигурация главного окна и центрального виджета
self.central_widget = QWidget(self)
self.setWindowTitle('Чтение БКУ')
self.setCentralWidget(self.central_widget)
self.layout_main_window = QVBoxLayout()
self.central_widget.setLayout(self.layout_main_window)
# конфигурация верхней панели инструментов
self.btn_start_reading = QPushButton("Считать")
self.btn_start_reading.clicked.connect(self.start_read)
self.btn_save_to_file = QPushButton("Экспорт")
self.btn_save_to_file.clicked.connect(self.save_to_file)
self.layout_toolbar = QHBoxLayout()
self.layout_toolbar.addStretch(1)
self.layout_toolbar.addWidget(self.btn_start_reading)
self.layout_toolbar.addWidget(self.btn_save_to_file)
self.layout_main_window.addLayout(self.layout_toolbar)
# конфигурация таблицы
self.layout_table = QHBoxLayout()
self.table = QTableWidget()
self.table.setColumnCount(9)
self.table.setRowCount(13500)
self.table.setHorizontalHeaderLabels(['№', 'Дата и время', 'БКУ', 'КЛ', 'АУ', 'Канал', 'Код события', 'Доп. параметр', 'Описание'])
self.table.horizontalHeader().setStretchLastSection(True)
self.table.horizontalHeader().setVisible(True)
self.layout_table.addWidget(self.table)
self.layout_main_window.addLayout(self.layout_table)
# конфигурация статус панели
self.layout_status_bar = QHBoxLayout()
self.layout_status_bar.addStretch(0)
self.layout_status_bar.setDirection(QBoxLayout.RightToLeft)
self.btn_select_port = QPushButton('Выбрать порт')
# +++
self.label_tx = QLabel('Tx:')
self.rb_tx = QRadioButton() # +++
self.rb_tx.setObjectName('rb_tx') # +++
self.label_rx = QLabel('Rx:')
self.rb_rx = QRadioButton() # +++
self.rb_rx.setObjectName('rb_rx') # +++
self.label_trans_packets = QLabel('Передано: 0 ')
self.label_rec_packets = QLabel('Принято: 0 ')
self.label_count_of_log_entries = QLabel('Количество записей: 0 ')
self.label_session_time = QLabel('00:00:00')
self.layout_status_bar.addWidget(self.label_session_time)
self.layout_status_bar.addWidget(self.label_count_of_log_entries)
self.layout_status_bar.addWidget(self.label_rec_packets)
self.layout_status_bar.addWidget(self.label_trans_packets)
# +++
self.layout_status_bar.addWidget(self.rb_rx) # +++
self.layout_status_bar.addWidget(self.label_rx)
self.layout_status_bar.addWidget(self.rb_tx) # +++
self.layout_status_bar.addWidget(self.label_tx)
self.layout_status_bar.addWidget(self.btn_select_port)
self.layout_main_window.addLayout(self.layout_status_bar)
self.thread = Thread() # +++
self.thread.dateSignal.connect(self.update_data) # +++
# +++ vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
size = 20
border = 2
self.setStyleSheet('''
#rb_rx::indicator, #rb_tx::indicator {{
border: {border}px solid #a35709;
height: {size}px;
width: {size}px;
border-radius: {radius}px;
background: qradialgradient(
cx:.5, cy:.5, radius: {innerRatio},
fx:.5, fy:.5,
stop:0 {color},
stop:0.45 {color},
stop:0.5 transparent,
stop:1 transparent
);
}}
#rb_rx::indicator:checked, #rb_tx::indicator:checked {{
background: qradialgradient(
cx:.5, cy:.5, radius: {innerRatio},
fx:.5, fy:.5,
stop:0 {checkColor},
stop:0.45 {checkColor},
stop:0.5 transparent,
stop:1 transparent
);
}}
'''.format(
size=size - border * 2,
border=border,
radius=size // 2,
innerRatio=1 - (border * 2 + 1) / size,
color='#ff0000',
checkColor='#bbff00',
))
def start_read(self):
self.thread.start()
def save_to_file(self):
pass
def update_data (self, text):
#print(f'{text}')
if text == 'Tx':
self.rb_tx.click()
elif text == 'Rx':
self.rb_rx.click()
# +++ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
if __name__ == '__main__':
app = QApplication(sys.argv)
window = MainWindow()
window.resize(700, 500)
window.show()
sys.exit(app.exec())
