wenet/rx/rx_gui.py

170 wiersze
5.0 KiB
Python

#!/usr/bin/env python
#
# SSDV RX GUI
#
# Copyright (C) 2019 Mark Jessop <vk5qi@rfhead.net>
2018-01-25 03:04:43 +00:00
# Released under GNU GPL v3 or later
#
# TODO:
# [x] Make functional under Python 2 & Python 3
# [ ] Completely replace with a browser-based interface.
#
import argparse
2019-07-26 14:00:02 +00:00
import logging
import json
import socket
import sys
2019-07-26 14:00:02 +00:00
import time
from WenetPackets import *
from threading import Thread
2019-07-26 14:00:02 +00:00
from PyQt5 import QtGui, QtCore, QtWidgets
from PyQt5.QtCore import Qt
2019-07-26 14:00:02 +00:00
try:
# Python 2
from Queue import Queue
except ImportError:
# Python 3
from queue import Queue
# Auto-resizing Widget, to contain displayed image.
2019-07-26 14:00:02 +00:00
class Label(QtWidgets.QLabel):
def __init__(self, img):
super(Label, self).__init__()
2019-07-26 14:00:02 +00:00
self.setFrameStyle(QtWidgets.QFrame.StyledPanel)
self.pixmap = QtGui.QPixmap()
2019-07-26 14:00:02 +00:00
def paintEvent(self, event):
size = self.size()
painter = QtGui.QPainter(self)
point = QtCore.QPoint(0,0)
scaledPix = self.pixmap.scaled(size, Qt.KeepAspectRatio, transformMode = Qt.SmoothTransformation)
# start painting the label from left upper corner
point.setX((size.width() - scaledPix.width())/2)
point.setY((size.height() - scaledPix.height())/2)
painter.drawPixmap(point, scaledPix)
2019-07-26 14:00:02 +00:00
class MyWindow(QtWidgets.QWidget):
def __init__(self, parent=None):
super(MyWindow, self).__init__(parent)
self.label = Label(self)
2019-07-26 14:00:02 +00:00
self.statusLabel = QtWidgets.QLabel("SSDV: No data yet.")
self.statusLabel.setFixedHeight(20)
self.uploaderLabel = QtWidgets.QLabel("Uploader: No Data Yet.")
self.uploaderLabel.setFixedHeight(20)
self.layout = QtWidgets.QVBoxLayout(self)
self.layout.addWidget(self.label)
self.layout.addWidget(self.statusLabel)
2019-07-26 14:00:02 +00:00
self.layout.addWidget(self.uploaderLabel)
self.rxqueue = Queue(32)
@QtCore.pyqtSlot(str)
def changeImage(self, pathToImage, text_message):
2019-07-26 14:00:02 +00:00
""" Load and display the supplied image, and update the status text field. """
logging.debug("New image: %s" % pathToImage)
pixmap = QtGui.QPixmap(pathToImage)
self.label.pixmap = pixmap
self.statusLabel.setText(text_message)
2019-07-26 14:00:02 +00:00
self.label.repaint()
logging.debug("Re-painted GUI.")
@QtCore.pyqtSlot(str)
def update_upload_status(self, queued, uploaded, discarded):
self.uploaderLabel.setText("Uploader: %d queued, %d uploaded, %d discarded." % (queued, uploaded, discarded))
def read_queue(self):
2019-07-26 14:00:02 +00:00
""" This function is called every 100ms in the QtGui thread. """
try:
new_packet = self.rxqueue.get_nowait()
packet_data = json.loads(new_packet)
2019-07-26 14:00:02 +00:00
if 'filename' in packet_data:
self.changeImage(packet_data['filename'],packet_data['text'])
elif 'uploader_status' in packet_data:
self.update_upload_status(packet_data['queued'], packet_data['uploaded'], packet_data['discarded'])
except:
2019-07-26 14:00:02 +00:00
# If there is nothing in the queue we will get a queue.Empty error, so we just return.
pass
2019-07-26 14:00:02 +00:00
# UDP Listener
udp_listener_running = False
udp_callback = None
2019-07-26 14:00:02 +00:00
def udp_rx():
global udp_listener_running, udp_callback
s = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
s.settimeout(1)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
try:
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
except:
pass
s.bind(('',WENET_IMAGE_UDP_PORT))
print("Started UDP Listener Thread.")
udp_listener_running = True
while udp_listener_running:
try:
m = s.recvfrom(512)
except socket.timeout:
m = None
if m != None:
2019-07-26 14:00:02 +00:00
try:
udp_callback(m[0])
except Exception as e:
pass
print("Closing UDP Listener")
s.close()
2019-07-26 14:00:02 +00:00
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("-v", "--verbose", action='store_true', default=False, help="Verbose output")
parser.add_argument("--image_port", type=int, default=None, help="UDP port used for communication between Wenet decoder processes. Default: 7890")
args = parser.parse_args()
if args.verbose:
log_level = logging.DEBUG
else:
log_level = logging.INFO
logging.basicConfig(format='%(asctime)s %(levelname)s: %(message)s', level=log_level)
2019-07-26 14:00:02 +00:00
# Overwrite the image UDP port if it has been provided
if args.image_port:
WENET_IMAGE_UDP_PORT = args.image_port
2019-07-26 14:00:02 +00:00
app = QtWidgets.QApplication(sys.argv)
app.setApplicationName('SSDV Viewer')
main = MyWindow()
main.resize(800,600)
2016-11-28 12:37:42 +00:00
main.setWindowTitle("SSDV Viewer")
udp_callback = main.rxqueue.put_nowait
t = Thread(target=udp_rx)
t.start()
timer = QtCore.QTimer()
timer.timeout.connect(main.read_queue)
timer.start(100)
main.show()
app.exec_()
udp_listener_running = False
2016-11-28 12:37:42 +00:00
sys.exit()