class ComPortClass(QObject): def __init__(self): self.SerialPort = QtSerialPort.QSerialPort() self.SerialPort.setBaudRate(115200) self.SerialPort.setPortName("COM8") self.SerialPort.readyRead.connect(self.ReadData) self.DATA_WAIT_SIZE = 0 self.DATA_BUFFER = QByteArray() self.DATA_MESSAGE = QByteArray() self.FLAG_WAIT_DATA = False def OpenPort(self): result = self.SerialPort.open(QtSerialPort.QSerialPort.ReadWrite) print(" PORT - ",self.SerialPort.portName()," OPENED") #self.Window.ui.ButtonOpenPort.clicked.connect(self.OpenPort) #self.Window.ui.ButtonSendData.clicked.connect(self.TestCOMConnection) #self.Window.ui.ButStepMotorRight.clicked.connect(lambda: self.MotorControl.MoveStepMotor(NumberMotor=0,Direction=1)) #self.Window.ui.ButStepMotorLeft.clicked.connect(lambda: self.MotorControl.MoveStepMotor(NumberMotor=1,Direction=-1)) def TestCOMConnection(self): self.HEADER_DATA = bytearray.fromhex("A1 F1 00") COMMAND_HEADER = bytearray.fromhex("01") self.DATA = COMMAND_HEADER + bytearray("TEST MESSAGE","utf-8") self.HEADER_DATA[2] = len(self.DATA) result = self.SerialPort.write(self.HEADER_DATA) result = self.SerialPort.write(self.DATA) print("SEND MESSAGE - ",self.DATA) def ClosePort(self): result = self.SerialPort.close() def ReadData(self): New_Data = self.SerialPort.readAll() self.DATA_BUFFER.append(New_Data) #print("BUFFER - " ,self.DATA_BUFFER.toHex(),"SIZE - ",self.DATA_BUFFER.length(),"WAIT - ",self.DATA_WAIT_SIZE) while(self.DATA_BUFFER.length() >= 3): if(self.DATA_BUFFER[0] == b'\xF1' and self.DATA_BUFFER[1] == b'\xA1'): self.DATA_WAIT_SIZE = self.DATA_BUFFER[2][0] self.DATA_BUFFER.remove(0,3) if(self.DATA_BUFFER.length() >= self.DATA_WAIT_SIZE): self.DATA_MESSAGE.clear() self.DATA_MESSAGE.append(self.DATA_BUFFER) self.DATA_BUFFER.remove(0,self.DATA_WAIT_SIZE) self.DATA_MESSAGE.truncate(self.DATA_WAIT_SIZE) print(self.DATA_BUFFER.toHex()) self.Window.AddText(" " + self.DATA_MESSAGE.data().decode(encoding="utf-8"),0) else: break;
def testThread(self): i = 0 array = QByteArray() while i <= 255: array.append('(') array.append(chr(i)) #self.senderMonitor.append("Iterator: {0}, chr(i): {1}".format(i, chr(i))) self.senderMonitor.append(str(i)) print("Iterator: {0}, chr(i): {1}".format(i, chr(i))) monitor.serialWrite(array) time.sleep(0.08) i += 1 array.clear()
class Handler(QRunnable): """ handle incoming connection, get data from client, extract information and add to queue """ def __init__(self, socketDescriptor, queues): super().__init__() self.socketDescriptor = socketDescriptor self.size = None self.priority = None self.timeout = None self.route_name = None self.route_code = None self.route = None self.call_back = None self.token = None self.module_version = None self.buffer = QByteArray() self.tcpSocket = None self.queues = queues def run(self): """ create new socket for communicate with client, receive header data contain request information, process it and send accept, then listen for receive body data """ self.tcpSocket = QtNetwork.QTcpSocket() if not self.tcpSocket.setSocketDescriptor(self.socketDescriptor): raise Exception(self.tcpSocket.errorString()) self.tcpSocket.waitForReadyRead() buffer = self.tcpSocket.readAll() try: try: self.size, self.priority, self.timeout, self.route, self.module_version, self.call_back, self.token = self.extract( buffer) except ValueError: self.size, self.priority, self.timeout, self.route, self.call_back, self.token = self.extract(buffer) self.call_back = base64.b64decode(self.call_back).decode() self.token = utils.decrypt_rsa(self.token, utils.get_rsa()) self.route_name = self.route_to_name(self.route) ApiLogging.info('route is: ' + self.route_name) if not self.module_version: self.module_version = 'v_1_0' except Exception as e: print("rejected", e) self.tcpSocket.write('{"status":"reject"}'.encode()) self.__close() else: self.size = int(self.size) self.tcpSocket.write('{"status":"accept"}'.encode()) self.tcpSocket.waitForBytesWritten() self.tcpSocket.readyRead.connect(self.__read_data) self.tcpSocket.waitForDisconnected( 30 * 60 * 1000) # FIXME: change to better solution for big data timeout and handle incompleted data @staticmethod def extract(buffer: QByteArray) -> str: """ extract 'size:priority:timeout:route:call_back:token' from header """ try: return buffer.data().decode().split(":") except ValueError: raise @staticmethod def route_to_name(route_code): try: result = ModuleModel.get(ModuleModel.code == route_code, ModuleModel.active == True) return result.alias except Exception: raise @staticmethod def route_to_group(route_name): try: result = ModuleModel.get(ModuleModel.alias == route_name) return result.category except Exception: return None def __read_data(self): """ slot called when data available in socket buffer for read after read all data, create new object contain mixed extracted header information and raw body data then add this new object to queue, clear buffer and close socket """ if self.tcpSocket.bytesAvailable() and self.size is not None: self.buffer.append(self.tcpSocket.readAll()) if self.size is not None and self.size == self.buffer.size(): data = self.buffer.data() uncompress_data = gzip_decompress(data) self.buffer.clear() self.buffer.append(uncompress_data) if Command.is_action(self.route): try: command_result = getattr(Command, self.route_name)(self.buffer.data()) compress_data = gzip_compress(utils.to_json({"status": command_result.get('status'), "data": command_result.get('data')}).encode()) self.tcpSocket.write(compress_data) self.__close() except Exception: self.__close() finally: self.buffer.clear() else: process_id = uuid.uuid4().hex request_object = RequestObject(self.route_name, self.call_back, self.token, process_id, self.buffer.data(), self.module_version) # TODO: add this object to RabbitMQ group = self.route_to_group(self.route_name) # FIXME: route_to_group try: if not group: self.buffer.clear() compress_data = gzip_compress('{"status":"failed","message":"this service is not categorized"}'.encode()) self.tcpSocket.write(compress_data) self.__close() else: # print('try connect to queue') self.queues.get(group).put(request_object,process_id) # print(group) # print('object added to queue') self.buffer.clear() compress_data = gzip_compress('{{"status":"success","process_id":"{0}"}}'.format(process_id).encode()) self.tcpSocket.write(compress_data) self.__close() except Exception: self.buffer.clear() compress_data = gzip_compress('{"status":"failed","message":"Internal Server Error"}'.encode()) self.tcpSocket.write(compress_data) self.__close() def __close(self): """ close socket connection """ self.tcpSocket.flush() self.tcpSocket.close() self.tcpSocket.deleteLater()
class QSerialDevice(QSerialPort): ''' Abstraction of an instrument connected to a serial port ... Attributes ---------- eol : str, optional End-of-line character. Default: '\r' (carriage return) manufacturer : str, optional Identifier for the serial interface manufacturer. Default: 'Prolific' baudrate : int, optional Baud rate for serial communication. Default: 9600 parity : int, optional One of the constants defined in the serial package stopbits : int, optional One of the constants defined in the serial package timeout : float Read timeout period [s]. Default: 0.1 Methods ------- find() : bool Find the serial device that satisfies identify(). Returns True if the device is found and correctly opened. identify() : bool Returns True if the device on the opened port correctly identifies itself. Subclasses must override this method. send(cmd) Write cmd to serial device with eol termination. Response is handled by call to process(). handshake(cmd) : str Write cmd to serial device and return response. Signals ------- dataReady(data) Emitted when eol-terminated data is returned by the device. ''' dataReady = pyqtSignal(str) def __init__(self, parent=None, port=None, eol='\r', manufacturer='Prolific', baudrate=QSerialPort.Baud9600, databits=QSerialPort.Data8, parity=QSerialPort.NoParity, stopbits=QSerialPort.OneStop, timeout=1000, **kwargs): super(QSerialDevice, self).__init__(parent=parent, **kwargs) self.eol = eol self.manufacturer = manufacturer self.baudrate = baudrate self.databits = databits self.parity = parity self.stopbits = stopbits self.timeout = timeout self.readyRead.connect(self.receive) self.buffer = QByteArray() if port is None: self.find() else: self.setup(port) if not self.isOpen(): raise ValueError('Could not find serial device') def setup(self, portinfo): if portinfo is None: logger.info('No serial port specified') return False name = portinfo.systemLocation() logger.debug(' Setting up {}'.format(name)) if portinfo.isBusy(): logger.debug(' Port is busy: {}'.format(name)) return False self.setPort(portinfo) self.setBaudRate(self.baudrate) self.setDataBits(self.databits) self.setParity(self.parity) self.setStopBits(self.stopbits) if not self.open(QSerialPort.ReadWrite): logger.debug(' Could not open port: {}'.format(name)) return False if self.bytesAvailable(): tmp = self.readAll() logger.info(' Cleared bytes from device: {}'.format(tmp)) if self.identify(): logger.info(' Device found at {}'.format(name)) return True self.close() logger.debug(' Device not connected to {}'.format(name)) return False def find(self): ''' Attempt to identify and open the serial port Returns ------- find : bool True if port identified and successfully opened. ''' ports = QSerialPortInfo.availablePorts() if len(ports) < 1: logger.warning(' No serial ports detected') return for port in ports: portinfo = QSerialPortInfo(port) if self.setup(portinfo): break def identify(self): ''' Identify this device Subclasses must override this method Returns ------- identify : bool True if attached device correctly identifies itself. ''' return True def send(self, data): ''' Write string to serial device with eol termination Parameters ---------- str : string String to be transferred ''' cmd = data + self.eol self.write(cmd.encode()) self.flush() logger.debug(' Data sent: {}'.format(data)) @pyqtSlot() def receive(self): ''' Slot for readyRead signal Appends data received from device to a buffer until eol character is received, then processes the contents of the buffer. ''' logger.debug(' Data received') self.buffer.append(self.readAll()) if self.buffer.contains(self.eol): logger.debug(' EOL character received') data = self.buffer.trimmed().data() # .decode() self.dataReady.emit(data) self.process(data) self.buffer.clear() def gets(self, raw=False): ''' Read characters from the serial port until eol is received Returns ------- s : str Decoded string ''' while not self.buffer.contains(self.eol): if self.waitForReadyRead(self.timeout): self.buffer.append(self.readAll()) else: logger.debug(' gets() timed out') break if raw: s = self.buffer.trimmed().data() else: s = self.buffer.trimmed().data().decode() logger.debug(' gets() received {} bytes: {}'.format(len(s), s)) self.buffer.clear() return s def handshake(self, cmd, raw=False): ''' Send command string to device and return the response from the device ... This form of communication bypasses the signal/slot mechanism and thus is blocking. Arguments --------- cmd : str String to be transmitted to device Returns ------- res : str Response from device ''' self.blockSignals(True) self.send(cmd) res = self.gets(raw) self.blockSignals(False) return res
class SerialWidget(QWidget): def __init__(self, parent=None): super().__init__(parent) self.__data = QByteArray() self.__serial = QSerialPort() self.__timer = QTimer(self) for info in QSerialPortInfo.availablePorts(): if info.description() == "USB-SERIAL CH340": self.__serial = QSerialPort(info) print(self.__serial.portName()) break self.__serial.readyRead.connect(self.__read_data) self.__timer.timeout.connect(self.__timer_update_com) self.__temperature = 0 self.__humidity = 0 self.__co2 = 0 self.__tvoc = 0 self.__pm25 = 0 self.__pm10 = 0 self.__o2 = 0 if self.__serial.open(QIODevice.ReadWrite): print("open success") else: print("open fail") self.__auto_save_thread = AutoSave(self) self.__auto_save_thread.start() def closeEvent(self, QCloseEvent): self.__auto_save_thread.kill() super().closeEvent(QCloseEvent) def __read_data(self): self.__timer.start(40) self.__data.append(self.__serial.readAll()) def __timer_update_com(self): self.__timer.stop() length = self.__data.length() i = 0 while i < length: num = ord(self.__data[i]) if num == 116: num = ord(self.__data[i + 1]) self.__temperature = num i += 1 print("temperature:" + str(self.__temperature)) elif num == 116 - ord('t') + ord('h'): num = ord(self.__data[i + 1]) self.__humidity = num i += 1 print("humidity:" + str(self.__humidity)) elif num == 116 - ord('t') + ord('c'): num = ord(self.__data[i + 1]) * 258 + ord(self.__data[i + 2]) self.__co2 = num i += 2 print("CO2:" + str(self.__co2)) num = ord(self.__data[i + 1]) * 258 + ord(self.__data[i + 2]) self.__tvoc = num i += 2 print("TVOC:" + str(self.__tvoc)) elif num == 116 - ord('t') + ord('o'): num = ord(self.__data[i + 1]) * 258 + ord(self.__data[i + 2]) num = num * (3300 / 4096) / 100 num = round(num, 3) self.__o2 = num i += 2 print("O2:" + str(self.__o2) + "%") elif num == 116 - ord('t') + ord('p'): num = ord(self.__data[i + 1]) * 258 + ord(self.__data[i + 2]) num /= 10 self.__pm25 = num i += 2 print("PM2.5:" + str(self.__pm25)) num = ord(self.__data[i + 1]) * 258 + ord(self.__data[i + 2]) num /= 10 self.__pm10 = num i += 2 print("PM10:" + str(self.__pm10)) i += 1 self.__data.clear() def get_temperature(self): return self.__temperature def get_humidity(self): return self.__humidity def get_co2(self): return self.__co2 def get_tvoc(self): return self.__tvoc def get_pm25(self): return self.__pm25 def get_pm10(self): return self.__pm10 def get_o2(self): return self.__o2
class rdcProtocol(serverProtocol.RDCServerProtocol): """ this class is inheritance from RDCServerProtocol, the class be responsible for achieve some of functions include ( making screen pixel, execute: mouse event, keyboard event, copy text, send cut text ) etc... """ def __init__(self): serverProtocol.RDCServerProtocol.__init__(self) self._array = QByteArray( ) self._buffer = QBuffer(self._array) self._buffer.open(QIODevice.WriteOnly) self._clipboard = QApplication.clipboard( ) self._maxWidth = QApplication.desktop( ).size( ).width( ) self._maxHeight = QApplication.desktop( ).size( ).height( ) self.keyboard = input.Keyboard( ) self.mouse = input.Mouse( ) def handleKeyEvent(self, key, flag=None): ''' if flag == 6: self.keyboard.press(key) else flag == 7: self.keyboard.release(key) ''' self.keyboard.press(key) self.keyboard.release(key) def handleMouseEvent(self, x, y, buttonmask=0, flag=None): print(x, y, buttonmask, flag) if flag == 5: # move mouse event self.mouse.move(x, y) elif flag == 2: # mouse button down self.mouse.press(x, y, buttonmask) elif flag == 3: # mouse button up self.mouse.release(x, y, buttonmask) elif flag == 4: # mouse button duble clicked self.mouse.press(x, y, buttonmask) self.mouse.release(x, y, buttonmask) def handleClientCopyText(self, text): """ copy text from client, and then set the text in clipboard """ self._clipboard.setText(text) def cutTextToClient(self): """ cut text to client """ text = self._clipboard.text( ) self.sendCutTextToClient(text) def _makeFramebuffer(self, width, height): screen = QApplication.primaryScreen() pix = screen.grabWindow(QApplication.desktop( ).winId( )) pix = pix.scaled(width, height) if width >= self._maxWidth or height >= self._maxHeight: width = self._maxWidth height = self._maxHeight pix.save(self._buffer, 'jpeg') pixData = self._buffer.data( ) self._array.clear( ) self._buffer.close( ) temp = "%s" % pixData result = temp[2:len(temp)-1] return result # return "%s" % pixData
class Connection(QTcpSocket): """ Class representing a peer connection. @signal readyForUse() emitted when the connection is ready for use @signal newMessage(user, message) emitted after a new message has arrived (string, string) @signal getParticipants() emitted after a get participants message has arrived @signal participants(participants) emitted after the list of participants has arrived (list of strings of "host:port") """ WaitingForGreeting = 0 ReadingGreeting = 1 ReadyForUse = 2 PlainText = 0 Ping = 1 Pong = 2 Greeting = 3 GetParticipants = 4 Participants = 5 Editor = 6 Undefined = 99 ProtocolMessage = "MESSAGE" ProtocolPing = "PING" ProtocolPong = "PONG" ProtocolGreeting = "GREETING" ProtocolGetParticipants = "GET_PARTICIPANTS" ProtocolParticipants = "PARTICIPANTS" ProtocolEditor = "EDITOR" readyForUse = pyqtSignal() newMessage = pyqtSignal(str, str) getParticipants = pyqtSignal() participants = pyqtSignal(list) editorCommand = pyqtSignal(str, str, str) rejected = pyqtSignal(str) def __init__(self, parent=None): """ Constructor @param parent referenec to the parent object (QObject) """ super(Connection, self).__init__(parent) self.__greetingMessage = self.tr("undefined") self.__username = self.tr("unknown") self.__serverPort = 0 self.__state = Connection.WaitingForGreeting self.__currentDataType = Connection.Undefined self.__numBytesForCurrentDataType = -1 self.__transferTimerId = 0 self.__isGreetingMessageSent = False self.__pingTimer = QTimer(self) self.__pingTimer.setInterval(PingInterval) self.__pongTime = QTime() self.__buffer = QByteArray() self.__client = None self.readyRead.connect(self.__processReadyRead) self.disconnected.connect(self.__disconnected) self.__pingTimer.timeout.connect(self.__sendPing) self.connected.connect(self.__sendGreetingMessage) def name(self): """ Public method to get the connection name. @return connection name (string) """ return self.__username def serverPort(self): """ Public method to get the server port. @return server port (integer) """ return self.__serverPort def setClient(self, client): """ Public method to set the reference to the cooperation client. @param client reference to the cooperation client (CooperationClient) """ self.__client = client def setGreetingMessage(self, message, serverPort): """ Public method to set the greeting message. @param message greeting message (string) @param serverPort port number to include in the message (integer) """ self.__greetingMessage = "{0}:{1}".format(message, serverPort) def sendMessage(self, message): """ Public method to send a message. @param message message to be sent (string) @return flag indicating a successful send (boolean) """ if message == "": return False msg = QByteArray(message.encode("utf-8")) data = QByteArray( "{0}{1}{2}{1}".format(Connection.ProtocolMessage, SeparatorToken, msg.size()).encode("utf-8")) + msg return self.write(data) == data.size() def timerEvent(self, evt): """ Protected method to handle timer events. @param evt reference to the timer event (QTimerEvent) """ if evt.timerId() == self.__transferTimerId: self.abort() self.killTimer(self.__transferTimerId) self.__transferTimerId = 0 def __processReadyRead(self): """ Private slot to handle the readyRead signal. """ if self.__state == Connection.WaitingForGreeting: if not self.__readProtocolHeader(): return if self.__currentDataType != Connection.Greeting: self.abort() return self.__state = Connection.ReadingGreeting if self.__state == Connection.ReadingGreeting: if not self.__hasEnoughData(): return self.__buffer = QByteArray( self.read(self.__numBytesForCurrentDataType)) if self.__buffer.size() != self.__numBytesForCurrentDataType: self.abort() return try: user, serverPort = \ str(self.__buffer, encoding="utf-8").split(":") except ValueError: self.abort() return self.__serverPort = int(serverPort) hostInfo = QHostInfo.fromName(self.peerAddress().toString()) self.__username = "******".format(user, hostInfo.hostName(), self.peerPort()) self.__currentDataType = Connection.Undefined self.__numBytesForCurrentDataType = 0 self.__buffer.clear() if not self.isValid(): self.abort() return bannedName = "{0}@{1}".format( user, hostInfo.hostName(), ) Preferences.syncPreferences() if bannedName in Preferences.getCooperation("BannedUsers"): self.rejected.emit( self.tr("* Connection attempted by banned user '{0}'."). format(bannedName)) self.abort() return if self.__serverPort != self.peerPort() and \ not Preferences.getCooperation("AutoAcceptConnections"): # don't ask for reverse connections or # if we shall accept automatically res = E5MessageBox.yesNo( None, self.tr("New Connection"), self.tr("""<p>Accept connection from """ """<strong>{0}@{1}</strong>?</p>""").format( user, hostInfo.hostName()), yesDefault=True) if not res: self.abort() return if self.__client is not None: chatWidget = self.__client.chatWidget() if chatWidget is not None and not chatWidget.isVisible(): e5App().getObject( "UserInterface").activateCooperationViewer() if not self.__isGreetingMessageSent: self.__sendGreetingMessage() self.__pingTimer.start() self.__pongTime.start() self.__state = Connection.ReadyForUse self.readyForUse.emit() while self.bytesAvailable(): if self.__currentDataType == Connection.Undefined: if not self.__readProtocolHeader(): return if not self.__hasEnoughData(): return self.__processData() def __sendPing(self): """ Private slot to send a ping message. """ if self.__pongTime.elapsed() > PongTimeout: self.abort() return self.write("{0}{1}1{1}p".format(Connection.ProtocolPing, SeparatorToken)) def __sendGreetingMessage(self): """ Private slot to send a greeting message. """ greeting = QByteArray(self.__greetingMessage.encode("utf-8")) data = QByteArray( "{0}{1}{2}{1}".format(Connection.ProtocolGreeting, SeparatorToken, greeting.size()).encode("utf-8")) + greeting if self.write(data) == data.size(): self.__isGreetingMessageSent = True def __readDataIntoBuffer(self, maxSize=MaxBufferSize): """ Private method to read some data into the buffer. @param maxSize maximum size of data to read (integer) @return size of data read (integer) """ if maxSize > MaxBufferSize: return 0 numBytesBeforeRead = self.__buffer.size() if numBytesBeforeRead == MaxBufferSize: self.abort() return 0 while self.bytesAvailable() and self.__buffer.size() < maxSize: self.__buffer.append(self.read(1)) if self.__buffer.endsWith(SeparatorToken): break return self.__buffer.size() - numBytesBeforeRead def __dataLengthForCurrentDataType(self): """ Private method to get the data length for the current data type. @return data length (integer) """ if self.bytesAvailable() <= 0 or \ self.__readDataIntoBuffer() <= 0 or \ not self.__buffer.endsWith(SeparatorToken): return 0 self.__buffer.chop(len(SeparatorToken)) number = self.__buffer.toInt()[0] self.__buffer.clear() return number def __readProtocolHeader(self): """ Private method to read the protocol header. @return flag indicating a successful read (boolean) """ if self.__transferTimerId: self.killTimer(self.__transferTimerId) self.__transferTimerId = 0 if self.__readDataIntoBuffer() <= 0: self.__transferTimerId = self.startTimer(TransferTimeout) return False self.__buffer.chop(len(SeparatorToken)) if self.__buffer == Connection.ProtocolPing: self.__currentDataType = Connection.Ping elif self.__buffer == Connection.ProtocolPong: self.__currentDataType = Connection.Pong elif self.__buffer == Connection.ProtocolMessage: self.__currentDataType = Connection.PlainText elif self.__buffer == Connection.ProtocolGreeting: self.__currentDataType = Connection.Greeting elif self.__buffer == Connection.ProtocolGetParticipants: self.__currentDataType = Connection.GetParticipants elif self.__buffer == Connection.ProtocolParticipants: self.__currentDataType = Connection.Participants elif self.__buffer == Connection.ProtocolEditor: self.__currentDataType = Connection.Editor else: self.__currentDataType = Connection.Undefined self.abort() return False self.__buffer.clear() self.__numBytesForCurrentDataType = \ self.__dataLengthForCurrentDataType() return True def __hasEnoughData(self): """ Private method to check, if enough data is available. @return flag indicating availability of enough data (boolean) """ if self.__transferTimerId: self.killTimer(self.__transferTimerId) self.__transferTimerId = 0 if self.__numBytesForCurrentDataType <= 0: self.__numBytesForCurrentDataType = \ self.__dataLengthForCurrentDataType() if self.bytesAvailable() < self.__numBytesForCurrentDataType or \ self.__numBytesForCurrentDataType <= 0: self.__transferTimerId = self.startTimer(TransferTimeout) return False return True def __processData(self): """ Private method to process the received data. """ self.__buffer = QByteArray(self.read( self.__numBytesForCurrentDataType)) if self.__buffer.size() != self.__numBytesForCurrentDataType: self.abort() return if self.__currentDataType == Connection.PlainText: self.newMessage.emit(self.__username, str(self.__buffer, encoding="utf-8")) elif self.__currentDataType == Connection.Ping: self.write("{0}{1}1{1}p".format(Connection.ProtocolPong, SeparatorToken)) elif self.__currentDataType == Connection.Pong: self.__pongTime.restart() elif self.__currentDataType == Connection.GetParticipants: self.getParticipants.emit() elif self.__currentDataType == Connection.Participants: msg = str(self.__buffer, encoding="utf-8") if msg == "<empty>": participantsList = [] else: participantsList = msg.split(SeparatorToken) self.participants.emit(participantsList[:]) elif self.__currentDataType == Connection.Editor: hash, fn, msg = \ str(self.__buffer, encoding="utf-8").split(SeparatorToken) self.editorCommand.emit(hash, fn, msg) self.__currentDataType = Connection.Undefined self.__numBytesForCurrentDataType = 0 self.__buffer.clear() def sendGetParticipants(self): """ Public method to request a list of participants. """ self.write("{0}{1}1{1}l".format(Connection.ProtocolGetParticipants, SeparatorToken)) def sendParticipants(self, participants): """ Public method to send the list of participants. @param participants list of participants (list of strings of "host:port") """ if participants: message = SeparatorToken.join(participants) else: message = "<empty>" msg = QByteArray(message.encode("utf-8")) data = QByteArray("{0}{1}{2}{1}".format( Connection.ProtocolParticipants, SeparatorToken, msg.size()).encode("utf-8")) + msg self.write(data) def sendEditorCommand(self, projectHash, filename, message): """ Public method to send an editor command. @param projectHash hash of the project (string) @param filename project relative universal file name of the sending editor (string) @param message editor command to be sent (string) """ msg = QByteArray("{0}{1}{2}{1}{3}".format(projectHash, SeparatorToken, filename, message).encode("utf-8")) data = QByteArray( "{0}{1}{2}{1}".format(Connection.ProtocolEditor, SeparatorToken, msg.size()).encode("utf-8")) + msg self.write(data) def __disconnected(self): """ Private slot to handle the connection being dropped. """ self.__pingTimer.stop() if self.__state == Connection.WaitingForGreeting: self.rejected.emit( self.tr("* Connection to {0}:{1} refused.").format( self.peerName(), self.peerPort()))
class Generator(QIODevice): def __init__(self, format, durationUs, sampleRate, parent): super(Generator, self).__init__(parent) self.m_pos = 0 self.m_buffer = QByteArray() self.generateData(format, durationUs, sampleRate) def start(self): self.open(QIODevice.ReadOnly) def stop(self): self.m_pos = 0 self.close() def generateData(self, format, durationUs, sampleRate): pack_format = '' if format.sampleSize() == 8: if format.sampleType() == QAudioFormat.UnSignedInt: scaler = lambda x: ((1.0 + x) / 2 * 255) pack_format = 'B' elif format.sampleType() == QAudioFormat.SignedInt: scaler = lambda x: x * 127 pack_format = 'b' elif format.sampleSize() == 16: if format.sampleType() == QAudioFormat.UnSignedInt: scaler = lambda x: (1.0 + x) / 2 * 65535 pack_format = '<H' if format.byteOrder() == QAudioFormat.LittleEndian else '>H' elif format.sampleType() == QAudioFormat.SignedInt: scaler = lambda x: x * 32767 pack_format = '<h' if format.byteOrder() == QAudioFormat.LittleEndian else '>h' assert(pack_format != '') channelBytes = format.sampleSize() // 8 sampleBytes = format.channelCount() * channelBytes length = (format.sampleRate() * format.channelCount() * (format.sampleSize() // 8)) * durationUs // 100000 self.m_buffer.clear() sampleIndex = 0 factor = 2 * pi * sampleRate / format.sampleRate() while length != 0: x = sin((sampleIndex % format.sampleRate()) * factor) packed = pack(pack_format, int(scaler(x))) for _ in range(format.channelCount()): self.m_buffer.append(packed) length -= channelBytes sampleIndex += 1 def readData(self, maxlen): data = QByteArray() total = 0 while maxlen > total: chunk = min(self.m_buffer.size() - self.m_pos, maxlen - total) data.append(self.m_buffer.mid(self.m_pos, chunk)) self.m_pos = (self.m_pos + chunk) % self.m_buffer.size() total += chunk return data.data() def writeData(self, data): return 0 def bytesAvailable(self): return self.m_buffer.size() + super(Generator, self).bytesAvailable()
class Uart(QSerialPort): signal_update_standard_gui = pyqtSignal(int) def __init__(self, parent=None): super(Uart, self).__init__(parent) # Qt 串口类 # self.com = QSerialPort() self.comParity = (QSerialPort.NoParity, QSerialPort.EvenParity, QSerialPort.OddParity, QSerialPort.SpaceParity, QSerialPort.MarkParity) self.list_of_msg = list() # 图像类 self.img = QPixmap() self.imgHeight = 80 self.imgWidth = 60 self.img_rx_data = QByteArray() self.totalImgSize = self.imgHeight * self.imgWidth # 上位机改参数类 self.ready_to_get_paras = False # self.imgrxData = bytearray() # self.pararxData = bytearray() # 标准模式类 self.standard_rx_data = QByteArray() self.change_paras = dict() # 上位机改参数字典 self.watch_paras = dict() # 上位机看参数 self.wave_paras = dict() # 波形字典 # 串口普通模式发送数据 def com_send_data(self, tx_data: str, is_hex: bool, codetype: str): if len(tx_data) == 0: return if not is_hex: self.write(tx_data.encode(codetype)) else: data = tx_data.replace(' ', '') # 如果16进制不是偶数个字符, 去掉最后一个, [ ]左闭右开 if len(data) % 2 == 1: data = data[0:len(data) - 1] # 如果遇到非16进制字符 # if data.isalnum() is False: # QMessageBox.critical(self, '错误', '包含非十六进制数') # try: hex_data = binascii.a2b_hex(data) # except: # QMessageBox.critical(self, '错误', '转换编码错误') # 发送16进制数据, 发送格式如 ‘31 32 33 41 42 43’, 代表'123ABC' # try: self.write(hex_data) # except: # QMessageBox.critical(self, '异常', '十六进制发送错误') return # 串口改参数模式发送函数 def com_send_change(self, name: str, tx_data_index: str, tx_data_value: str): if self.isOpen(): # self.paras.value = self.para_value.text() # print(self.index) tx_data0 = b'\xb1' # self.para_value.setText(tx_data_value) if tx_data_index.isalnum() and tx_data_value.isalnum(): self.write(tx_data0 + tx_data_index.encode() + b' ' + tx_data_value.encode() + b'\n\x00') self.change_paras[name] = tx_data_value # print("sendParasToMCU") # 串口接收模式处理函数 def com_receive_normal(self, is_hex: bool, code_type: str) -> str: rx_data = bytes(self.readAll()) if not is_hex: # code_type = selfboBox_codetype.currentText() # self.textEdit_Recive.insertPlainText(rx_data.decode(code_type, errors='replace')) return rx_data.decode(code_type, errors='replace') else: data = binascii.b2a_hex(rx_data).decode('ascii') # re 正则表达式 (.{2}) 匹配两个字母 hex_str = ' 0x'.join(re.findall('(.{2})', data)) # 补齐第一个 0x hex_str = '0x' + hex_str + ' ' return hex_str # 串口图像模式处理函数 def com_receive_image(self, cb_index, extra_bytes_len) -> (QBitmap, tuple): if len(self.img_rx_data) == 0: self.img_rx_data = self.readAll() # print(type(self.imgrxData)) if self.img_rx_data[:2] != b'\x01\xfe': # 不是图像的起始位 self.img_rx_data.clear() return None else: # self.imgrxData=self.imgrxData[2:] return None else: self.img_rx_data += self.readAll() # if self.imgrxData[:2]==b'\x01\xfe' and self.imgrxData[-2:]==b'\xfe\x01': if len( self.img_rx_data ) >= self.totalImgSize + 2 + extra_bytes_len: # 校验位两位,其余14位为传的数据 self.clear() # cb_index = selfboBox_imgType.currentIndex() extra_data = tuple(bytes( self.img_rx_data[2:2 + extra_bytes_len])) # 14位额外数据 # print(type( self.label_img.extra_data[0])) # print(self.label_img.extra_data) if cb_index == 0: # 二值化图像 self.img = QBitmap.fromData( QSize(self.imgWidth, self.imgHeight), bytes(self.img_rx_data[2 + extra_bytes_len:]), QImage.Format_Mono) elif cb_index == 1: # 灰度图像 # imgbytes = bytes(self.imgrxData[2:]) # self.img = QImage(imgbytes, self.imgWidth,self.imgHeight, QImage.Format_Mono) imgbytes = bytes([ 255 if int.from_bytes(b, 'little') > 0 else 0 for b in self.img_rx_data[2 + extra_bytes_len:] ]) self.img = QBitmap.fromImage( QImage(imgbytes, self.imgWidth, self.imgHeight, QImage.Format_Grayscale8)) # import numpy as np # a=np.frombuffer(bytes(self.imgrxData[2:]),dtype=np.uint8)*128 # imgbytes=bytes(a) # OpenCVUse.process(imgbytes, self.imgHeight, self.imgWidth) # self.label_img.setPixmap(self.img) self.img_rx_data.clear() return self.img, extra_data # 串口其他模式处理函数 def com_receive_standard(self): rx_data = self.readAll() self.standard_rx_data += rx_data while True: index = self.standard_rx_data.indexOf(b'\x00') if index < 0: # 直到self.standard_rx_data没有'\x00'跳出循环 break # rx_data.resize(index) standard_rx_data_temp = QByteArray(self.standard_rx_data[:index]) self.standard_rx_data = self.standard_rx_data[index + 1:] if len(standard_rx_data_temp) <= 0: continue # self.standard_rx_data.resize(self.standard_rx_data.indexOf(b'\x00')) self.list_of_msg = standard_rx_data_temp[1:].split('\n') # 字符串列表 msg = standard_rx_data_temp[0] # self.standard_rx_data.clear() if msg == b'\xa0': # 看参数模式 self.add_to_dict(self.watch_paras, self.list_of_msg) self.signal_update_standard_gui.emit(0) elif msg == b'\xa8': # 波形模式 self.add_to_dict(self.wave_paras, self.list_of_msg) self.signal_update_standard_gui.emit(2) elif msg == b'\xb2': # 改参数模式,读取参数 self.add_to_dict(self.change_paras, self.list_of_msg) self.signal_update_standard_gui.emit(1) elif msg == b'\xb0': # 改参数模式,成功修改参数 self.signal_update_standard_gui.emit(-1) # 将字符串添加到对应的字典中 @staticmethod def add_to_dict(dic: dict, list_of_msg: list): for entry in list_of_msg: if entry != b'': try: key, value = bytes(entry).split(b':', 1) dic[key.decode(errors='ignore')] = value.decode( errors='ignore') except ValueError: pass
class Connection(QTcpSocket): """ Class representing a peer connection. @signal readyForUse() emitted when the connection is ready for use @signal newMessage(user, message) emitted after a new message has arrived (string, string) @signal getParticipants() emitted after a get participants message has arrived @signal participants(participants) emitted after the list of participants has arrived (list of strings of "host:port") """ WaitingForGreeting = 0 ReadingGreeting = 1 ReadyForUse = 2 PlainText = 0 Ping = 1 Pong = 2 Greeting = 3 GetParticipants = 4 Participants = 5 Editor = 6 Undefined = 99 ProtocolMessage = "MESSAGE" ProtocolPing = "PING" ProtocolPong = "PONG" ProtocolGreeting = "GREETING" ProtocolGetParticipants = "GET_PARTICIPANTS" ProtocolParticipants = "PARTICIPANTS" ProtocolEditor = "EDITOR" readyForUse = pyqtSignal() newMessage = pyqtSignal(str, str) getParticipants = pyqtSignal() participants = pyqtSignal(list) editorCommand = pyqtSignal(str, str, str) rejected = pyqtSignal(str) def __init__(self, parent=None): """ Constructor @param parent referenec to the parent object (QObject) """ super(Connection, self).__init__(parent) self.__greetingMessage = self.tr("undefined") self.__username = self.tr("unknown") self.__serverPort = 0 self.__state = Connection.WaitingForGreeting self.__currentDataType = Connection.Undefined self.__numBytesForCurrentDataType = -1 self.__transferTimerId = 0 self.__isGreetingMessageSent = False self.__pingTimer = QTimer(self) self.__pingTimer.setInterval(PingInterval) self.__pongTime = QTime() self.__buffer = QByteArray() self.__client = None self.readyRead.connect(self.__processReadyRead) self.disconnected.connect(self.__disconnected) self.__pingTimer.timeout.connect(self.__sendPing) self.connected.connect(self.__sendGreetingMessage) def name(self): """ Public method to get the connection name. @return connection name (string) """ return self.__username def serverPort(self): """ Public method to get the server port. @return server port (integer) """ return self.__serverPort def setClient(self, client): """ Public method to set the reference to the cooperation client. @param client reference to the cooperation client (CooperationClient) """ self.__client = client def setGreetingMessage(self, message, serverPort): """ Public method to set the greeting message. @param message greeting message (string) @param serverPort port number to include in the message (integer) """ self.__greetingMessage = "{0}:{1}".format(message, serverPort) def sendMessage(self, message): """ Public method to send a message. @param message message to be sent (string) @return flag indicating a successful send (boolean) """ if message == "": return False msg = QByteArray(message.encode("utf-8")) data = QByteArray("{0}{1}{2}{1}".format( Connection.ProtocolMessage, SeparatorToken, msg.size()) .encode("utf-8")) + msg return self.write(data) == data.size() def timerEvent(self, evt): """ Protected method to handle timer events. @param evt reference to the timer event (QTimerEvent) """ if evt.timerId() == self.__transferTimerId: self.abort() self.killTimer(self.__transferTimerId) self.__transferTimerId = 0 def __processReadyRead(self): """ Private slot to handle the readyRead signal. """ if self.__state == Connection.WaitingForGreeting: if not self.__readProtocolHeader(): return if self.__currentDataType != Connection.Greeting: self.abort() return self.__state = Connection.ReadingGreeting if self.__state == Connection.ReadingGreeting: if not self.__hasEnoughData(): return self.__buffer = QByteArray( self.read(self.__numBytesForCurrentDataType)) if self.__buffer.size() != self.__numBytesForCurrentDataType: self.abort() return try: user, serverPort = \ str(self.__buffer, encoding="utf-8").split(":") except ValueError: self.abort() return self.__serverPort = int(serverPort) hostInfo = QHostInfo.fromName(self.peerAddress().toString()) self.__username = "******".format( user, hostInfo.hostName(), self.peerPort() ) self.__currentDataType = Connection.Undefined self.__numBytesForCurrentDataType = 0 self.__buffer.clear() if not self.isValid(): self.abort() return bannedName = "{0}@{1}".format( user, hostInfo.hostName(), ) Preferences.syncPreferences() if bannedName in Preferences.getCooperation("BannedUsers"): self.rejected.emit(self.tr( "* Connection attempted by banned user '{0}'.") .format(bannedName)) self.abort() return if self.__serverPort != self.peerPort() and \ not Preferences.getCooperation("AutoAcceptConnections"): # don't ask for reverse connections or # if we shall accept automatically res = E5MessageBox.yesNo( None, self.tr("New Connection"), self.tr("""<p>Accept connection from """ """<strong>{0}@{1}</strong>?</p>""").format( user, hostInfo.hostName()), yesDefault=True) if not res: self.abort() return if self.__client is not None: chatWidget = self.__client.chatWidget() if chatWidget is not None and not chatWidget.isVisible(): e5App().getObject( "UserInterface").activateCooperationViewer() if not self.__isGreetingMessageSent: self.__sendGreetingMessage() self.__pingTimer.start() self.__pongTime.start() self.__state = Connection.ReadyForUse self.readyForUse.emit() while self.bytesAvailable(): if self.__currentDataType == Connection.Undefined: if not self.__readProtocolHeader(): return if not self.__hasEnoughData(): return self.__processData() def __sendPing(self): """ Private slot to send a ping message. """ if self.__pongTime.elapsed() > PongTimeout: self.abort() return self.write("{0}{1}1{1}p".format( Connection.ProtocolPing, SeparatorToken)) def __sendGreetingMessage(self): """ Private slot to send a greeting message. """ greeting = QByteArray(self.__greetingMessage.encode("utf-8")) data = QByteArray("{0}{1}{2}{1}".format( Connection.ProtocolGreeting, SeparatorToken, greeting.size()) .encode("utf-8")) + greeting if self.write(data) == data.size(): self.__isGreetingMessageSent = True def __readDataIntoBuffer(self, maxSize=MaxBufferSize): """ Private method to read some data into the buffer. @param maxSize maximum size of data to read (integer) @return size of data read (integer) """ if maxSize > MaxBufferSize: return 0 numBytesBeforeRead = self.__buffer.size() if numBytesBeforeRead == MaxBufferSize: self.abort() return 0 while self.bytesAvailable() and self.__buffer.size() < maxSize: self.__buffer.append(self.read(1)) if self.__buffer.endsWith(SeparatorToken): break return self.__buffer.size() - numBytesBeforeRead def __dataLengthForCurrentDataType(self): """ Private method to get the data length for the current data type. @return data length (integer) """ if self.bytesAvailable() <= 0 or \ self.__readDataIntoBuffer() <= 0 or \ not self.__buffer.endsWith(SeparatorToken): return 0 self.__buffer.chop(len(SeparatorToken)) number = self.__buffer.toInt()[0] self.__buffer.clear() return number def __readProtocolHeader(self): """ Private method to read the protocol header. @return flag indicating a successful read (boolean) """ if self.__transferTimerId: self.killTimer(self.__transferTimerId) self.__transferTimerId = 0 if self.__readDataIntoBuffer() <= 0: self.__transferTimerId = self.startTimer(TransferTimeout) return False self.__buffer.chop(len(SeparatorToken)) if self.__buffer == Connection.ProtocolPing: self.__currentDataType = Connection.Ping elif self.__buffer == Connection.ProtocolPong: self.__currentDataType = Connection.Pong elif self.__buffer == Connection.ProtocolMessage: self.__currentDataType = Connection.PlainText elif self.__buffer == Connection.ProtocolGreeting: self.__currentDataType = Connection.Greeting elif self.__buffer == Connection.ProtocolGetParticipants: self.__currentDataType = Connection.GetParticipants elif self.__buffer == Connection.ProtocolParticipants: self.__currentDataType = Connection.Participants elif self.__buffer == Connection.ProtocolEditor: self.__currentDataType = Connection.Editor else: self.__currentDataType = Connection.Undefined self.abort() return False self.__buffer.clear() self.__numBytesForCurrentDataType = \ self.__dataLengthForCurrentDataType() return True def __hasEnoughData(self): """ Private method to check, if enough data is available. @return flag indicating availability of enough data (boolean) """ if self.__transferTimerId: self.killTimer(self.__transferTimerId) self.__transferTimerId = 0 if self.__numBytesForCurrentDataType <= 0: self.__numBytesForCurrentDataType = \ self.__dataLengthForCurrentDataType() if self.bytesAvailable() < self.__numBytesForCurrentDataType or \ self.__numBytesForCurrentDataType <= 0: self.__transferTimerId = self.startTimer(TransferTimeout) return False return True def __processData(self): """ Private method to process the received data. """ self.__buffer = QByteArray( self.read(self.__numBytesForCurrentDataType)) if self.__buffer.size() != self.__numBytesForCurrentDataType: self.abort() return if self.__currentDataType == Connection.PlainText: self.newMessage.emit( self.__username, str(self.__buffer, encoding="utf-8")) elif self.__currentDataType == Connection.Ping: self.write("{0}{1}1{1}p".format( Connection.ProtocolPong, SeparatorToken)) elif self.__currentDataType == Connection.Pong: self.__pongTime.restart() elif self.__currentDataType == Connection.GetParticipants: self.getParticipants.emit() elif self.__currentDataType == Connection.Participants: msg = str(self.__buffer, encoding="utf-8") if msg == "<empty>": participantsList = [] else: participantsList = msg.split(SeparatorToken) self.participants.emit(participantsList[:]) elif self.__currentDataType == Connection.Editor: hash, fn, msg = \ str(self.__buffer, encoding="utf-8").split(SeparatorToken) self.editorCommand.emit(hash, fn, msg) self.__currentDataType = Connection.Undefined self.__numBytesForCurrentDataType = 0 self.__buffer.clear() def sendGetParticipants(self): """ Public method to request a list of participants. """ self.write( "{0}{1}1{1}l".format( Connection.ProtocolGetParticipants, SeparatorToken) ) def sendParticipants(self, participants): """ Public method to send the list of participants. @param participants list of participants (list of strings of "host:port") """ if participants: message = SeparatorToken.join(participants) else: message = "<empty>" msg = QByteArray(message.encode("utf-8")) data = QByteArray("{0}{1}{2}{1}".format( Connection.ProtocolParticipants, SeparatorToken, msg.size()) .encode("utf-8")) + msg self.write(data) def sendEditorCommand(self, projectHash, filename, message): """ Public method to send an editor command. @param projectHash hash of the project (string) @param filename project relative universal file name of the sending editor (string) @param message editor command to be sent (string) """ msg = QByteArray("{0}{1}{2}{1}{3}".format( projectHash, SeparatorToken, filename, message).encode("utf-8")) data = QByteArray("{0}{1}{2}{1}".format( Connection.ProtocolEditor, SeparatorToken, msg.size()) .encode("utf-8")) + msg self.write(data) def __disconnected(self): """ Private slot to handle the connection being dropped. """ self.__pingTimer.stop() if self.__state == Connection.WaitingForGreeting: self.rejected.emit(self.tr( "* Connection to {0}:{1} refused.").format( self.peerName(), self.peerPort()))
class Widgets(QWidget): def __init__(self, dispositivoCamara, parent=None): super(Widgets, self).__init__(parent) self.parent = parent self.estadoFoto = False self.byteArrayFoto = QByteArray() # ========================================================== frame = QFrame(self) frame.setFrameShape(QFrame.Box) frame.setFrameShadow(QFrame.Sunken) frame.setFixedWidth(505) frame.setFixedHeight(380) frame.move(10, 10) # Instancias self.paginaVisor = QVideoWidget() self.paginaVisor.resize(500, 375) self.visor = QCameraViewfinder(self.paginaVisor) self.visor.resize(500, 375) self.labelFoto = QLabel() self.labelFoto.setAlignment(Qt.AlignCenter) self.labelFoto.resize(500, 375) # QStackedWidget self.stackedWidget = QStackedWidget(frame) self.stackedWidget.addWidget(self.paginaVisor) self.stackedWidget.addWidget(self.labelFoto) self.stackedWidget.resize(500, 375) self.stackedWidget.move(2, 2) # ======================== BOTONES ========================= self.buttonTomarFoto = QPushButton("Tomar foto", self) self.buttonTomarFoto.resize(110, 26) self.buttonTomarFoto.move(525, 10) self.buttonEliminarFoto = QPushButton("Eliminar foto", self) self.buttonEliminarFoto.resize(110, 26) self.buttonEliminarFoto.move(525, 50) self.buttonGuardarFoto = QPushButton("Guardar foto", self) self.buttonGuardarFoto.resize(110, 26) self.buttonGuardarFoto.move(525, 82) # ======================== EVENTOS ========================= self.buttonTomarFoto.clicked.connect(self.tomarFoto) self.buttonEliminarFoto.clicked.connect(self.eliminarFoto) self.buttonGuardarFoto.clicked.connect(self.guardarFoto) # ================== FUNCIONES AUTOMÁTICAS ================= self.setCamara(dispositivoCamara) # ======================= FUNCIONES ============================ def setCamara(self, dispositivoCamara): if dispositivoCamara.isEmpty(): self.camara = QCamera() else: self.camara = QCamera(dispositivoCamara) self.camara.stateChanged.connect(self.actualizarEstadoCamara) self.capturaImagen = QCameraImageCapture(self.camara) self.camara.setViewfinder(self.visor) self.actualizarEstadoCamara(self.camara.state()) self.capturaImagen.imageCaptured.connect(self.procesarImagenCapturada) self.capturaImagen.imageSaved.connect(self.imagenGuardada) self.camara.isCaptureModeSupported(QCamera.CaptureStillImage) self.camara.start() self.paginaVisor.update() def actualizarDispositivoCamara(self, action): self.setCamara(action.data()) def actualizarEstadoCamara(self, estado): if estado == QCamera.ActiveState: self.parent.accionIniciarCamara.setEnabled(False) self.parent.accionDetenerCamara.setEnabled(True) if not self.estadoFoto: self.buttonTomarFoto.setEnabled(True) self.buttonEliminarFoto.setEnabled(False) self.buttonGuardarFoto.setEnabled(False) elif estado in (QCamera.UnloadedState, QCamera.LoadedState): self.parent.accionIniciarCamara.setEnabled(True) self.parent.accionDetenerCamara.setEnabled(False) if not self.estadoFoto: self.buttonTomarFoto.setEnabled(False) self.buttonEliminarFoto.setEnabled(False) self.buttonGuardarFoto.setEnabled(False) def iniciarCamara(self): self.camara.start() def detenerCamara(self): self.camara.stop() def tomarFoto(self): rutaFoto = "{}/fotoTemporal.jpg".format(getcwd()) self.capturaImagen.capture(rutaFoto) self.estadoFoto = True def procesarImagenCapturada(self, requestId, imagen): foto = QPixmap.fromImage(imagen) buffer = QBuffer(self.byteArrayFoto) buffer.open(QIODevice.WriteOnly) buffer.close() foto.save(buffer, "PNG") fotoEscalada = foto.scaled(self.labelFoto.size()) self.labelFoto.setPixmap(fotoEscalada) self.mostrarImagenCapturada() def visualizarVisor(self): self.stackedWidget.setCurrentIndex(0) def mostrarImagenCapturada(self): self.stackedWidget.setCurrentIndex(1) self.buttonTomarFoto.setEnabled(False) self.buttonEliminarFoto.setEnabled(True) self.buttonGuardarFoto.setEnabled(True) def imagenGuardada(self, id, nombreFoto): if QFile.exists(nombreFoto): remove(nombreFoto) def eliminarFoto(self): self.estadoFoto = False self.byteArrayFoto.clear() self.labelFoto.clear() self.actualizarEstadoCamara(self.camara.state()) self.visualizarVisor() def guardarFoto(self): guardarComo, extension = QFileDialog.getSaveFileName( self, "Guardar como", "Foto", "JPG (*.jpg);;PNG (*.png);;ICO (*.ico);;BMP (*.bmp)", options=QFileDialog.Options()) if guardarComo: foto = QPixmap() foto.loadFromData(self.byteArrayFoto, "PNG", Qt.AutoColor) foto.save(guardarComo, quality=100) QMessageBox.information( self, "Guardar foto", "Foto guardada con éxito ") self.eliminarFoto()
class MainForm(QDialog): def __init__(self, parent=None): super(MainForm, self).__init__(parent) self.filename = "" self.copiedItem = QByteArray() self.pasteOffset = 5 self.prevPoint = QPoint() self.addOffset = 5 self.borders = [] self.printer = QPrinter(QPrinter.HighResolution) # enum QPrinter::PrinterMode # HighRes是一个高分辨率模式,是PrinterMode组成 self.printer.setPageSize(QPrinter.A4) self.view = GraphicsView() self.scene = QGraphicsScene(self) self.scene.setSceneRect(0, 0, PageSize[0], PageSize[1]) self.addBorders() self.view.setScene(self.scene) # 不用写 view.show? self.wrapped = [] # Needed to keep wrappers alive buttonLayout = QVBoxLayout() for text, slot in (("Add &Text", self.addText), ("Add &Box", self.addBox), ("Add Pi&xmap", self.addPixmap), ("&Align", None), ("&Copy", self.copy), ("C&ut", self.cut), ("&Paste", self.paste), ("&Delete...", self.delete), ("&Rotate", self.rotate), ("Pri&nt...", self.print_), ("&Open...", self.open), ("&Save", self.save), ("&Quit", self.accept)): button = QPushButton(text) if not MAC: button.setFocusPolicy(Qt.NoFocus) if slot is not None: button.clicked.connect(slot) if text == "&Align": menu = QMenu(self) for text, arg in (("Align &Left", Qt.AlignLeft), ("Align &Right", Qt.AlignRight), ("Align &Top", Qt.AlignTop), ("Align &Bottom", Qt.AlignBottom)): wrapper = functools.partial(self.setAlignment, arg) # ????? self.wrapped.append(wrapper) menu.addAction(text, wrapper) button.setMenu(menu) if text == "Pri&nt...": buttonLayout.addStretch(5) if text == "&Quit": buttonLayout.addStretch(1) buttonLayout.addWidget(button) buttonLayout.addStretch() layout = QHBoxLayout() layout.addWidget(self.view, 1) # QBoxLayout::addWidget(QWidget *widget, int stretch = 0, Qt::Alignment alignment = Qt::Alignment()) layout.addLayout(buttonLayout) self.setLayout(layout) fm = QFontMetrics(self.font()) self.resize(self.scene.width() + fm.width(" Delete... ") + 50, self.scene.height() + 50) self.setWindowTitle("Page Designer 页面设计器") def addBorders(self): '''添加出血框和打印边界框,对scene进行操作同时添加到self.borders这一列表中''' self.borders = [] rect = QRectF(0, 0, PageSize[0], PageSize[1]) self.borders.append(self.scene.addRect( rect, Qt.black)) # addRect px,py,x,y,QPen,QBrush or QRectF,QPen,QBrush # scene.addRect(): Return QGraphicsRectItem;Inherits: QGraphicsItem margin = 5.25 * PointSize self.borders.append( self.scene.addRect(rect.adjusted(margin, margin, -margin, -margin), Qt.red)) def removeBorders(self): '''从列表删除边框,从scene删除边框''' while self.borders: item = self.borders.pop() self.scene.removeItem( item ) #Removes the item item and all its children from the scene. 接受参数为QGraphicsItem del item def reject(self): self.accept() def accept(self): self.offerSave() QDialog.accept( self ) # 完成提示保存之后传递给QDialog的accept命令,之前几章好像讲过为什么要直接调用QDialog这个父类,这里的MWindow是QDialog def offerSave(self): '''根据Dirty判断是否更改,如果更改则弹出保存对话框,调用save()函数进行保存。''' if (Dirty and QMessageBox.question( self, "Page Designer - Unsaved Changes", "Save unsaved changes?", QMessageBox.Yes | QMessageBox.No) == QMessageBox.Yes): self.save() def position(self): point = self.mapFromGlobal(QCursor.pos( )) # mFG接受一个QPoint参数,包含两个元素的元组 此函数转换QPoint到map,返回依旧是QPoint # Translates the global screen coordinate pos to widget coordinates. if not self.view.geometry().contains( point): #?????????????????????????????????????????????? coord = random.randint(36, 144) point = QPoint(coord, coord) else: if point == self.prevPoint: point += QPoint(self.addOffset, self.addOffset) self.addOffset += 5 else: self.addOffset = 5 self.prevPoint = point return self.view.mapToScene( point) # 将Widght的点左边转换成为Scene坐标,调用对象是QGView def addText(self): dialog = TextItemDlg(position=self.position(), scene=self.scene, parent=self) dialog.exec_() def addBox(self): BoxItem(self.position(), self.scene) def addPixmap(self): path = (QFileInfo(self.filename).path() if self.filename else "." ) # 获取filename定义的正确地址,或者返回此程序根目录 fname, filetype = QFileDialog.getOpenFileName( self, "Page Designer - Add Pixmap", path, "Pixmap Files (*.bmp *.jpg *.png *.xpm)") if not fname: return self.createPixmapItem( QPixmap(fname), self.position()) # 插入时候要将地址传递给QPixmap生成对象,并且还需要位置参数 def createPixmapItem(self, pixmap, position, matrix=QTransform()): # 传递参数为:文件、位置和变换 item = GraphicsPixmapItem(pixmap) # 第一步,将QPixmap转换成为GPItem item.setFlags(QGraphicsItem.ItemIsSelectable | QGraphicsItem.ItemIsMovable) # 设置一些属性 item.setPos(position) # 设置位置 item.setTransform(matrix) # 将变换参数应用到GPItem之中 self.scene.clearSelection() # 选择清空 self.scene.addItem(item) # 添加项目 item.setSelected(True) # 并且选中 global Dirty Dirty = True # 全局变量Dirty设置为True return item # 为什么需要返回这个??? def selectedItem( self): # 默认的scene选择的是一个列表,如果只有一个则返回index=0的item,如果多选则不返回任何一个 items = self.scene.selectedItems() if len(items) == 1: return items[0] return None def copy(self): item = self.selectedItem() if item is None: return self.copiedItem.clear() self.pasteOffset = 5 stream = QDataStream(self.copiedItem, QIODevice.WriteOnly) self.writeItemToStream(stream, item) # 写入到流 def cut(self): item = self.selectedItem() if item is None: return self.copy() self.scene.removeItem(item) del item def paste(self): if self.copiedItem.isEmpty(): return stream = QDataStream(self.copiedItem, QIODevice.ReadOnly) self.readItemFromStream( stream, self.pasteOffset) # 从数据流中读入信息,并且输出到self.pasteOffset中 self.pasteOffset += 5 def setAlignment(self, alignment): # Items are returned in arbitrary order items = self.scene.selectedItems() if len(items) <= 1: return # Gather coordinate data leftXs, rightXs, topYs, bottomYs = [], [], [], [] for item in items: rect = item.sceneBoundingRect() # Returns the bounding rect of this item in scene coordinates : Return QRectF leftXs.append(rect.x()) rightXs.append(rect.x() + rect.width()) topYs.append(rect.y()) bottomYs.append(rect.y() + rect.height()) # Perform alignment if alignment == Qt.AlignLeft: xAlignment = min(leftXs) for i, item in enumerate(items): item.moveBy(xAlignment - leftXs[i], 0) # void QGraphicsItem::moveBy(qreal dx, qreal dy) # Moves the item by dx points horizontally, and dy point vertically. elif alignment == Qt.AlignRight: xAlignment = max(rightXs) for i, item in enumerate(items): item.moveBy(xAlignment - rightXs[i], 0) elif alignment == Qt.AlignTop: yAlignment = min(topYs) for i, item in enumerate(items): item.moveBy(0, yAlignment - topYs[i]) elif alignment == Qt.AlignBottom: yAlignment = max(bottomYs) for i, item in enumerate(items): item.moveBy(0, yAlignment - bottomYs[i]) global Dirty Dirty = True def rotate(self): for item in self.scene.selectedItems(): item.setRotation(item.rotation() + 30) def delete(self): # 从基本scene属性中选取选择的多个,弹出对话框,如果允许,则迭代进行删除,并且设置Dirty为True items = self.scene.selectedItems() if (len(items) and QMessageBox.question( self, "Page Designer - Delete", "Delete {0} item{1}?".format( len(items), "s" if len(items) != 1 else ""), QMessageBox.Yes | QMessageBox.No) == QMessageBox.Yes): while items: item = items.pop() self.scene.removeItem(item) del item global Dirty Dirty = True def print_(self): # dialog = QPrintDialog(self.printer) # 在此已经设置好了self.printer 也就是QPrinter对象,QPDlg直接传递回了Printer对象,之后重新由 # # printer对象声称心的QPrinter就可以继续使用在这句话中设置好的参数了。 # if dialog.exec_(): painter = QPainter(self.printer) painter.setRenderHint(QPainter.Antialiasing) painter.setRenderHint(QPainter.TextAntialiasing) self.scene.clearSelection() self.removeBorders() self.scene.render(painter) # [void] Renders the source rect from scene into target, using painter. This function is useful for capturing the contents # of the scene onto a paint device, such as a QImage (e.g., to take a screenshot), or for printing with QPrinter. For example: self.addBorders() def open(self): self.offerSave() path = (QFileInfo(self.filename).path() if self.filename else ".") fname, filetype = QFileDialog.getOpenFileName( self, "Page Designer - Open", path, "cmPage Designer Files (*.cmpd *.pgd *.cmd)") if not fname: return self.filename = fname fh = None try: fh = QFile(self.filename) if not fh.open(QIODevice.ReadOnly): raise IOError(str(fh.errorString())) items = self.scene.items() # 返回所有的QGitem List形式 while items: item = items.pop() # 从列表中删除一个,从scene中删除一个,迭代到全部删除 self.scene.removeItem(item) del item self.addBorders() stream = QDataStream(fh) stream.setVersion(QDataStream.Qt_5_7) magic = stream.readInt32() if magic != MagicNumber: raise IOError("not a valid .cmpd file") fileVersion = stream.readInt16() if fileVersion != FileVersion: raise IOError("unrecognised .cmpd file version") while not fh.atEnd(): self.readItemFromStream(stream) except IOError as e: QMessageBox.warning( self, "Page Designer -- Open Error", "Failed to open {0}: {1}".format(self.filename, e)) finally: if fh is not None: fh.close() global Dirty Dirty = False def save(self): if not self.filename: path = "." fname, filetype = QFileDialog.getSaveFileName( self, "Page Designer - Save As", path, "cmPage Designer Files (*.cmpd *.pgd *.cmd)") if not fname: return self.filename = fname fh = None try: fh = QFile(self.filename) if not fh.open(QIODevice.WriteOnly): raise IOError(str(fh.errorString())) self.scene.clearSelection() stream = QDataStream(fh) stream.setVersion(QDataStream.Qt_5_7) stream.writeInt32(MagicNumber) stream.writeInt16(FileVersion) for item in self.scene.items(): self.writeItemToStream(stream, item) except IOError as e: QMessageBox.warning( self, "Page Designer -- Save Error", "Failed to save {0}: {1}".format(self.filename, e)) finally: if fh is not None: fh.close() global Dirty Dirty = False def readItemFromStream(self, stream, offset=0): type = "" position = QPointF() matrix = QTransform() rotateangle = 0 #add by yangrongdong type = stream.readQString() stream >> position >> matrix if offset: position += QPointF(offset, offset) if type == "Text": text = "" font = QFont() text = stream.readQString() stream >> font rotateangle = stream.readFloat() tx = TextItem(text, position, self.scene, font, matrix) tx.setRotation(rotateangle) elif type == "Box": rect = QRectF() stream >> rect style = Qt.PenStyle(stream.readInt16()) rotateangle = stream.readFloat() bx = BoxItem(position, self.scene, style, rect, matrix) bx.setRotation(rotateangle) elif type == "Pixmap": pixmap = QPixmap() stream >> pixmap rotateangle = stream.readFloat() px = self.createPixmapItem(pixmap, position, matrix) px.setRotation(rotateangle) def writeItemToStream(self, stream, item): if isinstance(item, TextItem): stream.writeQString("Text") stream << item.pos() << item.transform() stream.writeQString(item.toPlainText()) stream << item.font() stream.writeFloat(item.rotation()) #add by yangrongdong elif isinstance(item, GraphicsPixmapItem): stream.writeQString("Pixmap") stream << item.pos() << item.transform() << item.pixmap() stream.writeFloat(item.rotation()) #add by yangrongdong elif isinstance(item, BoxItem): stream.writeQString("Box") stream << item.pos() << item.transform() << item.rect stream.writeInt16(item.style) stream.writeFloat(item.rotation()) #add by yangrongdong
class Ui(QtWidgets.QMainWindow): def __init__(self, *args, **kwargs): super(Ui, self).__init__(*args, **kwargs) uic.loadUi('terminal_display.ui', self) self.serialData = QByteArray().append("created ") self.receivedData = QByteArray() self.transmitData = QByteArray() self.serialPort = QtSerialPort.QSerialPort() self.serialPort.setPortName("COM10") self.serialPort.setBaudRate(115200) self.serialPort.setFlowControl(self.serialPort.NoFlowControl) self.serialPort.setStopBits(self.serialPort.OneStop) self.serialPort.readyRead.connect(self.onreadyread) self.serialPort.bytesWritten.connect(self.onbyteswritten) ports = QtSerialPort.QSerialPortInfo.availablePorts() print(ports) for eachPort in ports: print(eachPort.portName()) print("open : ", self.serialPort.open(QtCore.QIODevice.ReadWrite), self.serialPort.portName()) self.packet = b'' self.packetCounter = 0 palette = QPalette() palette.setColor(QPalette.Window, QColor(53, 53, 53)) palette.setColor(QPalette.WindowText, QColor(255, 255, 255)) palette.setColor(QPalette.Base, QColor(25, 25, 25)) palette.setColor(QPalette.AlternateBase, QColor(53, 53, 53)) palette.setColor(QPalette.ToolTipBase, QColor(255, 255, 255)) palette.setColor(QPalette.ToolTipText, QColor(255, 255, 255)) palette.setColor(QPalette.Text, QColor(255, 255, 255)) palette.setColor(QPalette.Button, QColor(53, 53, 53)) palette.setColor(QPalette.ButtonText, QColor(255, 255, 255)) palette.setColor(QPalette.BrightText, QColor(255, 255, 255)) palette.setColor(QPalette.Link, QColor(42, 130, 218)) palette.setColor(QPalette.Highlight, QColor(42, 130, 218)) palette.setColor(QPalette.HighlightedText, QColor(0, 0, 0)) app.setPalette(palette) ''' self.testTimer = QTimer() self.testTimer.setInterval(10) self.testTimer.timeout.connect(self.timeToSend) self.i=0 self.counter=0 self.formattedi="" self.bytearrayToSend=QByteArray(4,'a') self.testTimer.start() ''' self.show() def timeToSend(self): self.bytearrayToSend.clear() formattedi = '%04d' % self.i self.bytearrayToSend.append(formattedi) print("go ", self.formattedi) print(self.bytearrayToSend) self.serialPort.writeData(self.bytearrayToSend) self.i = (self.i + 1) % 256 def onbyteswritten(self, bytes): # self.serialPort.flush() # print("onbyteswritten",bytes) # print("bytestowrite",self.serialPort.bytesToWrite()) # print(self.serialPort.readBufferSize()) # print() pass def onreadyread(self): # self.serialPort.flush() self.receivedData = self.serialPort.readAll() while len(self.receivedData) > 64: index = self.receivedData.indexOf(b'\x14', 0) print("index : ", index, "len : ", len(self.packet)) self.packet = self.receivedData[index:index + 64] self.packetCounter += 1 print(self.packetCounter, "th packet", self.packet) print("remaining stream : ", len(self.receivedData), self.receivedData) self.receivedData = self.receivedData[index + 64:] print("after strip : ", len(self.receivedData), self.receivedData) if len(self.packet) == 64: self.parse() else: print("packet size miss, skip.") print() def parse(self): year = int.from_bytes(self.packet[0], "big") month = int.from_bytes(self.packet[1], "big") day = int.from_bytes(self.packet[2], "big") hour = int.from_bytes(self.packet[3], "big") minute = int.from_bytes(self.packet[4], "big") second = int.from_bytes(self.packet[5], "big") print(year, month, day, hour, minute, second) date = QDate(year + 2000, month, day) time = QTime(hour, minute, second) self.dateTimeEdit.setDate(date) self.dateTimeEdit.setTime(time) [index, gyrox, gyroy, gyroz, accx, accy, accz, magx, magy, magz, ch1_volt, ch1_amp, ch2_volt, ch2_amp] = \ struct.unpack("iiiiiiiiiififi", self.packet[8:64]) print("stream index : ", index) print("gyro : ", gyrox, gyroy, gyroz) print("acc : ", accx, accy, accz) print("mag : ", magx, magy, magz) print("ch1 : ", ch1_volt, ch1_amp) print("ch2 : ", ch2_volt, ch2_amp) self.Index_lineEdit.setText(str(index)) self.lineEdit_Status_gyrox.setText(str(gyrox)) self.lineEdit_Status_gyroy.setText(str(gyroy)) self.lineEdit_Status_gyroz.setText(str(gyroz)) self.lineEdit_Status_accx.setText(str(accx)) self.lineEdit_Status_accy.setText(str(accy)) self.lineEdit_Status_accz.setText(str(accz)) self.lineEdit_Status_magx.setText(str(magx)) self.lineEdit_Status_magy.setText(str(magy)) self.lineEdit_Status_magz.setText(str(magz)) self.lineEdit_Ch1_vol.setText(str(ch1_volt)) self.lineEdit_Ch1_amp.setText(str(ch1_amp)) self.lineEdit_Ch2_vol.setText(str(ch2_volt)) self.lineEdit_Ch2_amp.setText(str(ch2_amp)) def commandstart(self): print("command start") self.serialPort.writeData(b'\x01\x00') def commandstop(self): print("command stop") self.serialPort.writeData(b'\x00\x00') def SingleModeClicked(self, On): if On: print("Single mode on") self.serialPort.writeData(b'\x02\x00') else: print("Single mode off") def MultiModeClicked(self, On): if On: print("Multimode on") self.serialPort.writeData(b'\x02\x01') else: print("Multimode off") def changeIntensityValue(self, value): print("intensity value ", value) self.receivedData.clear() print("data to append : ", QByteArray.number(value, 16)) print("QByteArray after append") self.receivedData.append(QByteArray.fromHex(QByteArray.number(3, 16))) self.receivedData.append( QByteArray.fromHex(QByteArray.number(value, 16))) print(self.receivedData) self.serialPort.writeData(self.receivedData) self.receivedData.clear()
class Window(QWidget): def __init__(self, parent=None): QWidget.__init__(self, parent) format = QAudioFormat() format.setChannelCount(1) format.setSampleRate(22050) format.setSampleSize(16) format.setCodec("audio/pcm") format.setByteOrder(QAudioFormat.LittleEndian) format.setSampleType(QAudioFormat.SignedInt) self.output = QAudioOutput(format, self) self.frequency = 440 self.volume = 0 self.buffer = QBuffer() self.data = QByteArray() self.deviceLineEdit = QLineEdit() self.deviceLineEdit.setReadOnly(True) self.deviceLineEdit.setText( QAudioDeviceInfo.defaultOutputDevice().deviceName()) self.pitchSlider = QSlider(Qt.Horizontal) self.pitchSlider.setMaximum(100) self.volumeSlider = QSlider(Qt.Horizontal) self.volumeSlider.setMaximum(32767) self.volumeSlider.setPageStep(1024) self.playButton = QPushButton(self.tr("&Play")) self.pitchSlider.valueChanged.connect(self.changeFrequency) self.volumeSlider.valueChanged.connect(self.changeVolume) self.playButton.clicked.connect(self.play) formLayout = QFormLayout() formLayout.addRow(self.tr("Device:"), self.deviceLineEdit) formLayout.addRow(self.tr("P&itch:"), self.pitchSlider) formLayout.addRow(self.tr("&Volume:"), self.volumeSlider) buttonLayout = QVBoxLayout() buttonLayout.addWidget(self.playButton) buttonLayout.addStretch() horizontalLayout = QHBoxLayout(self) horizontalLayout.addLayout(formLayout) horizontalLayout.addLayout(buttonLayout) self.play() self.createData() def changeFrequency(self, value): self.frequency = 440 + (value * 2) self.createData() def play(self): if self.output.state() == QAudio.ActiveState: self.output.stop() if self.buffer.isOpen(): self.buffer.close() if self.output.error() == QAudio.UnderrunError: self.output.reset() self.buffer.setData(self.data) self.buffer.open(QIODevice.ReadOnly) self.buffer.seek(0) self.output.start(self.buffer) def changeVolume(self, value): self.volume = value self.createData() def createData(self): self.data.clear() for i in range(2 * 22050): t = i / 22050.0 value = int(self.volume * sin(2 * pi * self.frequency * t)) self.data.append(struct.pack("<h", value))
class Generator(QIODevice): def __init__(self, format, durationUs, sampleRate, parent): super(Generator, self).__init__(parent) self.m_pos = 0 self.m_buffer = QByteArray() self.generateData(format, durationUs, sampleRate) def start(self): self.open(QIODevice.ReadOnly) def stop(self): self.m_pos = 0 self.close() def generateData(self, format, durationUs, sampleRate): pack_format = '' if format.sampleSize() == 8: if format.sampleType() == QAudioFormat.UnSignedInt: scaler = lambda x: ((1.0 + x) / 2 * 255) pack_format = 'B' elif format.sampleType() == QAudioFormat.SignedInt: scaler = lambda x: x * 127 pack_format = 'b' elif format.sampleSize() == 16: if format.sampleType() == QAudioFormat.UnSignedInt: scaler = lambda x: (1.0 + x) / 2 * 65535 pack_format = '<H' if format.byteOrder( ) == QAudioFormat.LittleEndian else '>H' elif format.sampleType() == QAudioFormat.SignedInt: scaler = lambda x: x * 32767 pack_format = '<h' if format.byteOrder( ) == QAudioFormat.LittleEndian else '>h' assert (pack_format != '') channelBytes = format.sampleSize() // 8 sampleBytes = format.channelCount() * channelBytes length = (format.sampleRate() * format.channelCount() * (format.sampleSize() // 8)) * durationUs // 100000 self.m_buffer.clear() sampleIndex = 0 factor = 2 * pi * sampleRate / format.sampleRate() while length != 0: x = sin((sampleIndex % format.sampleRate()) * factor) packed = pack(pack_format, int(scaler(x))) for _ in range(format.channelCount()): self.m_buffer.append(packed) length -= channelBytes sampleIndex += 1 def readData(self, maxlen): data = QByteArray() total = 0 while maxlen > total: chunk = min(self.m_buffer.size() - self.m_pos, maxlen - total) data.append(self.m_buffer.mid(self.m_pos, chunk)) self.m_pos = (self.m_pos + chunk) % self.m_buffer.size() total += chunk return data.data() def writeData(self, data): return 0 def bytesAvailable(self): return self.m_buffer.size() + super(Generator, self).bytesAvailable()
def Ustaw90(): IK = IK_class() time.sleep(2.5) array = QByteArray() test = IK.IK_LP(-85, -118, 0) print("{1}, {0}".format(test, "LP")) array.append(chr(16)) array.append('|') array.append(chr(int(test[0]))) array.append('|') array.append(chr(254)) array.append('#') array.append(chr(17)) array.append('|') array.append(chr(int(test[1]))) array.append('|') array.append(chr(254)) array.append('#') array.append(chr(18)) array.append('|') array.append(chr(int(test[2]))) array.append('|') array.append(chr(254)) array.append('#') test = IK.IK_LS(-85, -118, 0) print("{1}, {0}".format(test, "LS")) array.append(chr(13)) array.append('|') array.append(chr(int(test[0]))) array.append('|') array.append(chr(254)) array.append('#') array.append(chr(14)) array.append('|') array.append(chr(int(test[1]))) array.append('|') array.append(chr(254)) array.append('#') array.append(chr(15)) array.append('|') array.append(chr(int(test[2]))) array.append('|') array.append(chr(254)) array.append('#') test = IK.IK_LT(-85, -118, 0) print("{1}, {0}".format(test, "LT")) array.append(chr(10)) array.append('|') array.append(chr(int(test[0]))) array.append('|') array.append(chr(254)) array.append('#') array.append(chr(11)) array.append('|') array.append(chr(int(test[1]))) array.append('|') array.append(chr(254)) array.append('#') array.append(chr(12)) array.append('|') array.append(chr(int(test[2]))) array.append('|') array.append(chr(254)) array.append('#') test = IK.IK_PP(85, -118, 0) print("{1}, {0}".format(test, "PP")) array.append(chr(7)) array.append('|') array.append(chr(int(test[0]))) array.append('|') array.append(chr(254)) array.append('#') array.append(chr(8)) array.append('|') array.append(chr(int(test[1]))) array.append('|') array.append(chr(254)) array.append('#') array.append(chr(9)) array.append('|') array.append(chr(int(test[2]))) array.append('|') array.append(chr(254)) array.append('#') test = IK.IK_PS(85, -118, 0) print("{1}, {0}".format(test, "PS")) array.append(chr(4)) array.append('|') array.append(chr(int(test[0]))) array.append('|') array.append(chr(254)) array.append('#') array.append(chr(5)) array.append('|') array.append(chr(int(test[1]))) array.append('|') array.append(chr(254)) array.append('#') array.append(chr(6)) array.append('|') array.append(chr(int(test[2]))) array.append('|') array.append(chr(254)) array.append('#') test = IK.IK_PT(85, -118, 0) print("{1}, {0}".format(test, "PT")) array.append(chr(1)) array.append('|') array.append(chr(int(test[0]))) array.append('|') array.append(chr(254)) array.append('#') array.append(chr(2)) array.append('|') array.append(chr(int(test[1]))) array.append('|') array.append(chr(254)) array.append('#') array.append(chr(3)) array.append('|') array.append(chr(int(test[2]))) array.append('|') array.append(chr(255)) array.append('#') okno.monitor.serialWrite(array) time.sleep(2) for i in range(0, 1): array.clear() test = IK.IK_PP(85, -118, -40) print("{1}, {0}".format(test, "PT")) array.append(chr(7)) array.append('|') array.append(chr(int(test[0]))) array.append('|') array.append(chr(254)) array.append('#') array.append(chr(8)) array.append('|') array.append(chr(int(test[1]))) array.append('|') array.append(chr(254)) array.append('#') array.append(chr(9)) array.append('|') array.append(chr(int(test[2]))) array.append('|') array.append(chr(254)) array.append('#') test = IK.IK_PS(85, -118, -40) print("{1}, {0}".format(test, "PT")) array.append(chr(4)) array.append('|') array.append(chr(int(test[0]))) array.append('|') array.append(chr(254)) array.append('#') array.append(chr(5)) array.append('|') array.append(chr(int(test[1]))) array.append('|') array.append(chr(254)) array.append('#') array.append(chr(6)) array.append('|') array.append(chr(int(test[2]))) array.append('|') array.append(chr(254)) array.append('#') test = IK.IK_PT(85, -118, -40) print("{1}, {0}".format(test, "PT")) array.append(chr(1)) array.append('|') array.append(chr(int(test[0]))) array.append('|') array.append(chr(254)) array.append('#') array.append(chr(2)) array.append('|') array.append(chr(int(test[1]))) array.append('|') array.append(chr(254)) array.append('#') array.append(chr(3)) array.append('|') array.append(chr(int(test[2]))) array.append('|') array.append(chr(255)) array.append('#') okno.monitor.serialWrite(array) time.sleep(1) array.clear() test = IK.IK_PP(85, -118, 40) print("{1}, {0}".format(test, "PT")) array.append(chr(7)) array.append('|') array.append(chr(int(test[0]))) array.append('|') array.append(chr(254)) array.append('#') array.append(chr(8)) array.append('|') array.append(chr(int(test[1]))) array.append('|') array.append(chr(254)) array.append('#') array.append(chr(9)) array.append('|') array.append(chr(int(test[2]))) array.append('|') array.append(chr(254)) array.append('#') test = IK.IK_PS(85, -118, 40) print("{1}, {0}".format(test, "PT")) array.append(chr(4)) array.append('|') array.append(chr(int(test[0]))) array.append('|') array.append(chr(254)) array.append('#') array.append(chr(5)) array.append('|') array.append(chr(int(test[1]))) array.append('|') array.append(chr(254)) array.append('#') array.append(chr(6)) array.append('|') array.append(chr(int(test[2]))) array.append('|') array.append(chr(254)) array.append('#') test = IK.IK_PT(85, -118, 40) print("{1}, {0}".format(test, "PT")) array.append(chr(1)) array.append('|') array.append(chr(int(test[0]))) array.append('|') array.append(chr(254)) array.append('#') array.append(chr(2)) array.append('|') array.append(chr(int(test[1]))) array.append('|') array.append(chr(254)) array.append('#') array.append(chr(3)) array.append('|') array.append(chr(int(test[2]))) array.append('|') array.append(chr(255)) array.append('#') okno.monitor.serialWrite(array) time.sleep(1)
class MainForm(QDialog): def __init__(self, parent=None): super(MainForm, self).__init__(parent) self.filename = "" self.copiedItem = QByteArray() self.pasteOffset = 5 self.prevPoint = QPoint() self.addOffset = 5 self.borders = [] self.printer = QPrinter(QPrinter.HighResolution) self.printer.setPageSize(QPrinter.Letter) self.view = GraphicsView() self.scene = QGraphicsScene(self) self.scene.setSceneRect(0, 0, PageSize[0], PageSize[1]) self.addBorders() self.view.setScene(self.scene) self.wrapped = [] # Needed to keep wrappers alive buttonLayout = QVBoxLayout() for text, slot in ( ("Add &Text", self.addText), ("Add &Box", self.addBox), ("Add Pi&xmap", self.addPixmap), ("&Align", None), ("&Copy", self.copy), ("C&ut", self.cut), ("&Paste", self.paste), ("&Delete...", self.delete), ("&Rotate", self.rotate), ("Pri&nt...", self.print_), ("&Open...", self.open), ("&Save", self.save), ("&Quit", self.accept)): button = QPushButton(text) if not MAC: button.setFocusPolicy(Qt.NoFocus) if slot is not None: button.clicked.connect(slot) if text == "&Align": menu = QMenu(self) for text, arg in ( ("Align &Left", Qt.AlignLeft), ("Align &Right", Qt.AlignRight), ("Align &Top", Qt.AlignTop), ("Align &Bottom", Qt.AlignBottom)): wrapper = functools.partial(self.setAlignment, arg) self.wrapped.append(wrapper) menu.addAction(text, wrapper) button.setMenu(menu) if text == "Pri&nt...": buttonLayout.addStretch(5) if text == "&Quit": buttonLayout.addStretch(1) buttonLayout.addWidget(button) buttonLayout.addStretch() layout = QHBoxLayout() layout.addWidget(self.view, 1) layout.addLayout(buttonLayout) self.setLayout(layout) fm = QFontMetrics(self.font()) self.resize(self.scene.width() + fm.width(" Delete... ") + 50, self.scene.height() + 50) self.setWindowTitle("Page Designer") def addBorders(self): self.borders = [] rect = QRectF(0, 0, PageSize[0], PageSize[1]) self.borders.append(self.scene.addRect(rect, Qt.yellow)) margin = 5.25 * PointSize self.borders.append(self.scene.addRect( rect.adjusted(margin, margin, -margin, -margin), Qt.yellow)) def removeBorders(self): while self.borders: item = self.borders.pop() self.scene.removeItem(item) del item def reject(self): self.accept() def accept(self): self.offerSave() QDialog.accept(self) def offerSave(self): if (Dirty and QMessageBox.question(self, "Page Designer - Unsaved Changes", "Save unsaved changes?", QMessageBox.Yes|QMessageBox.No) == QMessageBox.Yes): self.save() def position(self): point = self.mapFromGlobal(QCursor.pos()) if not self.view.geometry().contains(point): coord = random.randint(36, 144) point = QPoint(coord, coord) else: if point == self.prevPoint: point += QPoint(self.addOffset, self.addOffset) self.addOffset += 5 else: self.addOffset = 5 self.prevPoint = point return self.view.mapToScene(point) def addText(self): dialog = TextItemDlg(position=self.position(), scene=self.scene, parent=self) dialog.exec_() def addBox(self): BoxItem(self.position(), self.scene) def addPixmap(self): path = (QFileInfo(self.filename).path() if self.filename else ".") fname,filetype = QFileDialog.getOpenFileName(self, "Page Designer - Add Pixmap", path, "Pixmap Files (*.bmp *.jpg *.png *.xpm)") if not fname: return self.createPixmapItem(QPixmap(fname), self.position()) def createPixmapItem(self, pixmap, position, matrix=QTransform()): item = GraphicsPixmapItem(pixmap) item.setFlags(QGraphicsItem.ItemIsSelectable| QGraphicsItem.ItemIsMovable) item.setPos(position) item.setTransform(matrix) self.scene.clearSelection() self.scene.addItem(item) item.setSelected(True) global Dirty Dirty = True return item def selectedItem(self): items = self.scene.selectedItems() if len(items) == 1: return items[0] return None def copy(self): item = self.selectedItem() if item is None: return self.copiedItem.clear() self.pasteOffset = 5 stream = QDataStream(self.copiedItem, QIODevice.WriteOnly) self.writeItemToStream(stream, item) def cut(self): item = self.selectedItem() if item is None: return self.copy() self.scene.removeItem(item) del item def paste(self): if self.copiedItem.isEmpty(): return stream = QDataStream(self.copiedItem, QIODevice.ReadOnly) self.readItemFromStream(stream, self.pasteOffset) self.pasteOffset += 5 def setAlignment(self, alignment): # Items are returned in arbitrary order items = self.scene.selectedItems() if len(items) <= 1: return # Gather coordinate data leftXs, rightXs, topYs, bottomYs = [], [], [], [] for item in items: rect = item.sceneBoundingRect() leftXs.append(rect.x()) rightXs.append(rect.x() + rect.width()) topYs.append(rect.y()) bottomYs.append(rect.y() + rect.height()) # Perform alignment if alignment == Qt.AlignLeft: xAlignment = min(leftXs) for i, item in enumerate(items): item.moveBy(xAlignment - leftXs[i], 0) elif alignment == Qt.AlignRight: xAlignment = max(rightXs) for i, item in enumerate(items): item.moveBy(xAlignment - rightXs[i], 0) elif alignment == Qt.AlignTop: yAlignment = min(topYs) for i, item in enumerate(items): item.moveBy(0, yAlignment - topYs[i]) elif alignment == Qt.AlignBottom: yAlignment = max(bottomYs) for i, item in enumerate(items): item.moveBy(0, yAlignment - bottomYs[i]) global Dirty Dirty = True def rotate(self): for item in self.scene.selectedItems(): item.setRotation(item.rotation()+30) def delete(self): items = self.scene.selectedItems() if (len(items) and QMessageBox.question(self, "Page Designer - Delete", "Delete {0} item{1}?".format(len(items), "s" if len(items) != 1 else ""), QMessageBox.Yes|QMessageBox.No) == QMessageBox.Yes): while items: item = items.pop() self.scene.removeItem(item) del item global Dirty Dirty = True def print_(self): dialog = QPrintDialog(self.printer) if dialog.exec_(): painter = QPainter(self.printer) painter.setRenderHint(QPainter.Antialiasing) painter.setRenderHint(QPainter.TextAntialiasing) self.scene.clearSelection() self.removeBorders() self.scene.render(painter) self.addBorders() def open(self): self.offerSave() path = (QFileInfo(self.filename).path() if self.filename else ".") fname,filetype = QFileDialog.getOpenFileName(self, "Page Designer - Open", path, "Page Designer Files (*.pgd)") if not fname: return self.filename = fname fh = None try: fh = QFile(self.filename) if not fh.open(QIODevice.ReadOnly): raise IOError(str(fh.errorString())) items = self.scene.items() while items: item = items.pop() self.scene.removeItem(item) del item self.addBorders() stream = QDataStream(fh) stream.setVersion(QDataStream.Qt_5_7) magic = stream.readInt32() if magic != MagicNumber: raise IOError("not a valid .pgd file") fileVersion = stream.readInt16() if fileVersion != FileVersion: raise IOError("unrecognised .pgd file version") while not fh.atEnd(): self.readItemFromStream(stream) except IOError as e: QMessageBox.warning(self, "Page Designer -- Open Error", "Failed to open {0}: {1}".format(self.filename, e)) finally: if fh is not None: fh.close() global Dirty Dirty = False def save(self): if not self.filename: path = "." fname,filetype = QFileDialog.getSaveFileName(self, "Page Designer - Save As", path, "Page Designer Files (*.pgd)") if not fname: return self.filename = fname fh = None try: fh = QFile(self.filename) if not fh.open(QIODevice.WriteOnly): raise IOError(str(fh.errorString())) self.scene.clearSelection() stream = QDataStream(fh) stream.setVersion(QDataStream.Qt_5_7) stream.writeInt32(MagicNumber) stream.writeInt16(FileVersion) for item in self.scene.items(): self.writeItemToStream(stream, item) except IOError as e: QMessageBox.warning(self, "Page Designer -- Save Error", "Failed to save {0}: {1}".format(self.filename, e)) finally: if fh is not None: fh.close() global Dirty Dirty = False def readItemFromStream(self, stream, offset=0): type = "" position = QPointF() matrix = QTransform() rotateangle=0#add by yangrongdong type=stream.readQString() stream >> position >> matrix if offset: position += QPointF(offset, offset) if type == "Text": text = "" font = QFont() text=stream.readQString() stream >> font rotateangle=stream.readFloat() tx=TextItem(text, position, self.scene, font, matrix) tx.setRotation(rotateangle) elif type == "Box": rect = QRectF() stream >> rect style = Qt.PenStyle(stream.readInt16()) rotateangle=stream.readFloat() bx=BoxItem(position, self.scene, style, rect, matrix) bx.setRotation(rotateangle) elif type == "Pixmap": pixmap = QPixmap() stream >> pixmap rotateangle=stream.readFloat() px=self.createPixmapItem(pixmap, position, matrix) px.setRotation(rotateangle) def writeItemToStream(self, stream, item): if isinstance(item, TextItem): stream.writeQString("Text") stream<<item.pos()<< item.transform() stream.writeQString(item.toPlainText()) stream<< item.font() stream.writeFloat(item.rotation())#add by yangrongdong elif isinstance(item, GraphicsPixmapItem): stream.writeQString("Pixmap") stream << item.pos() << item.transform() << item.pixmap() stream.writeFloat(item.rotation())#add by yangrongdong elif isinstance(item, BoxItem): stream.writeQString("Box") stream<< item.pos() << item.transform() << item.rect stream.writeInt16(item.style) stream.writeFloat(item.rotation())#add by yangrongdong
def data(self, position: int, maxSize: int = -1, highlighted: QByteArray = None) -> QByteArray: delta = 0 chunkIdx = 0 chunk = Chunk() buffer = QByteArray() if highlighted: highlighted.clear() if position >= self.size: return buffer if maxSize < 0: maxSize = self.size elif (position + maxSize) > self.size: maxSize = self.size - position self.device.open(QIODevice.ReadOnly) while maxSize > 0: chunk.absPos = sys.maxsize chunksLoopOngoing = True while chunkIdx < len(self.chunks) and chunksLoopOngoing: # In this section, we track changes before our required data and # we take the editdet data, if availible. ioDelta is a difference # counter to justify the read pointer to the original data, if # data in between was deleted or inserted. chunk = self.chunks[chunkIdx] if chunk.absPos > position: chunksLoopOngoing = False else: count = 0 chunkIdx += 1 chunkOfs = position - chunk.absPos if maxSize > chunk.data.size() - chunkOfs: count = chunk.data.size() - chunkOfs delta += CHUNK_SIZE - chunk.data.size() else: count = maxSize if count > 0: buffer += chunk.data.mid(chunkOfs, count) maxSize -= count position += count if highlighted: highlighted += chunk.dataChanged.mid( chunkOfs, count) if maxSize > 0 and position < chunk.absPos: byteCount = 0 if (chunk.absPos - position) > maxSize: byteCount = maxSize else: byteCount = chunk.absPos - position maxSize -= byteCount self.device.seek(position + delta) readBuffer = self.device.read(byteCount) buffer += readBuffer if highlighted: highlighted += QByteArray(readBuffer.size(), NORMAL) position += len(readBuffer) self.device.close() return buffer