class ExportViewTarget(object): def __init__(self, project, filename, parent): self.mutex = QMutex() self.project = project self.filename = filename self.parent = parent self.surface = QOffscreenSurface() self.surface.setFormat(QSurfaceFormat.defaultFormat()) self.surface.create() def destroy(self): self.surface.destroy() def render(self, view, uniforms=dict()): self.project.setCameraMode('view') self.project.setCameraViewRef(view) self.project.setCameraAtOrigin() self.project.render(self.ctx.functions(), view.info.width, view.info.height, uniforms) depth = self.project.renderer.depthmap(self.ctx.functions(), view.info.width, view.info.height) return depth def __enter__(self): self.mutex.lock() self.ctx = QOpenGLContext() self.ctx.setShareContext(self.parent) self.ctx.create() if not self.ctx.makeCurrent(self.surface): raise Exception("cannot make context current") self.project.renderer.lock() def __exit__(self, type, value, tb): self.project.renderer.unlock() self.ctx.doneCurrent() del self.ctx self.mutex.unlock()
def __init__(self, cfg, tracker=None, server_addr=None, events_server_addr=None, sharing_server_addr=None, upload_server_addr=None, parent=None): logger.debug("Initializing API server client...") QObject.__init__(self, parent=parent) self._sessions = dict() self.server_addr = server_addr if server_addr \ else API_URI.format(cfg.host) self.events_server_addr = events_server_addr if events_server_addr \ else API_EVENTS_URI.format(cfg.host) self.sharing_server_addr = sharing_server_addr if sharing_server_addr \ else API_SHARING_URI.format(cfg.host) self.upload_server_addr = upload_server_addr if upload_server_addr \ else API_UPLOAD_URI.format(cfg.host) self._tracker = tracker self.ip_addr = None self.cfg = cfg self.node_sign = None self._ip_lock = QMutex(parent=self) self._os_name, self._is_server = get_os_name_and_is_server()
class Barrier: """ Implement a barrier, such that threads block until other monitored threads reach a specific location. The barrier can be used multiple times (it is reinitialized after the threads passed). See https://stackoverflow.com/questions/9637374/qt-synchronization-barrier/9639624#9639624 """ def __init__(self, count): self.count = count self.origCount = count self.mutex = QMutex() self.condition = QWaitCondition() def wait(self): """ Wait until all monitored threads called wait. :return: None """ self.mutex.lock() self.count -= 1 if self.count > 0: self.condition.wait(self.mutex) else: self.count = self.origCount self.condition.wakeAll() self.mutex.unlock()
def __init__(self): self.ser = serial.Serial() self.escape = 0 self.connected = 0 self.state = WAITING_DLE self.crc_data = [] self.data = [] self.mutex = QMutex()
def __init__(self, parent=None): super(FortuneThread, self).__init__(parent) self.quit = False self.hostName = '' self.cond = QWaitCondition() self.mutex = QMutex() self.port = 0
def __init__(self, project, filename, parent): self.mutex = QMutex() self.project = project self.filename = filename self.parent = parent self.surface = QOffscreenSurface() self.surface.setFormat(QSurfaceFormat.defaultFormat()) self.surface.create()
class TestThread(QThread): startRecording = Signal() def __init__(self, config, aruco_tester_widget, acs_control, parent=None): QThread.__init__(self, parent) self.config = config self.aruco_tester_widget = aruco_tester_widget self.image_miner = aruco_tester_widget.image_miner self.acs_control = acs_control self.startRecording.connect(self.aruco_tester_widget.onRecordClicked) self.recordingStopped = QWaitCondition() self.mutex = QMutex() @Slot() def wake(self): self.recordingStopped.wakeAll() pass def run(self): print('starting...') base_dir = os.path.dirname(os.path.realpath(__file__)) config = self.config['config'] angles = self.config['angles'] j = 0 self.image_miner.set_video_capture_property('CAP_PROP_BRIGHTNESS', 50.5/100.) self.image_miner.set_video_capture_property('CAP_PROP_CONTRAST', 50.5/100.) self.image_miner.set_video_capture_property('CAP_PROP_SATURATION', 50.5/100.) prop = 'CAP_PROP_BRIGHTNESS' print(prop) start = config[prop]['start'] end = config[prop]['end'] step = config[prop]['step'] for i in range(start, end+1, step): print(i) self.image_miner.set_video_capture_property(prop, i/100.) series_dir = os.path.join(base_dir, str(prop), str(i), str(self.aruco_tester_widget.use_board)) j += 1 for angle in angles: fileName = os.path.join(series_dir, str(angle)) print(angle) self.acs_control.pa(angle) time.sleep(5) self.mutex.lock() self.startRecording.emit() print('wait for recording to stop') self.recordingStopped.wait(self.mutex) print('saving data to {}'.format(fileName)) self.aruco_tester_widget.broadcaster.saveToFile(fileName) self.mutex.unlock() self.acs_control.pa(0) time.sleep(10)
def __init__(self): super(Operator, self).__init__() logging.debug('Operator::__init__() called') self.threadpool = QThreadPool.globalInstance() self.procHandleMutex = QMutex() self._startAll = OperatorStartAll(self) self.identGenMutex = QMutex() self.n_ident = 0
def __init__(self, config, aruco_tester_widget, acs_control, parent=None): QThread.__init__(self, parent) self.config = config self.aruco_tester_widget = aruco_tester_widget self.image_miner = aruco_tester_widget.image_miner self.acs_control = acs_control self.startRecording.connect(self.aruco_tester_widget.onRecordClicked) self.recordingStopped = QWaitCondition() self.mutex = QMutex()
def __init__(self, thread_pool: QThreadPool): """ Runs a runnable on a thread pool, canceling the previous runnable if it is still enqueued. Parameters ---------- thread_pool The thread pool that will be used to run the runnable. """ super().__init__() self._thread_pool = thread_pool self._current_runnable = None self._lock = QMutex()
def __init__(self, func_id, parent=None): super().__init__(parent) self.func_id = func_id self.call_graph = nx.DiGraph() self.mutex = QMutex() self._abort = False
def __init__(self, config): # pylint: disable=unused-argument super().__init__() self._deviceId = 0 self._registeredDevices = {} self._mutex = QMutex() self._recordingActive = False self._appConn = None
def __init__(self, parent=None): super(RenderThread, self).__init__(parent) self.mutex = QMutex() self.condition = QWaitCondition() self.centerX = 0.0 self.centerY = 0.0 self.scaleFactor = 0.0 self.resultSize = QSize() self.colormap = [] self.restart = False self.abort = False for i in range(RenderThread.ColormapSize): self.colormap.append(self.rgbFromWaveLength(380.0 + (i * 400.0 / RenderThread.ColormapSize)))
def __init__(self): super(MainWindow, self).__init__() self.ui = Ui_MainWindow() self.ui.setupUi(self) self.signals = MainWindowSignals() self.save_data_dir = None self.current_measurement = 0 self.max_measurements = 0 self.collecting = False self.time_axis = None self.mutex = QMutex() self.comp_thread = QThread() self.exp_thread = QThread() self._connect_components() self._set_initial_widget_states() self._store_line_objects() self._set_plot_mouse_mode()
def __init__(self, multicast_addr, port, parent=None): super().__init__(parent) self.multicast_addr = multicast_addr self.port = port self.bind_addr = '0.0.0.0' self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) self.worker = _Worker(self.messageReceivedSignal, self.sock, self) self.mutex = QMutex()
def __init__(self): super().__init__() self.__activeCount: int = 0 # number of operations in progress centralWidget = MainWidget() self.setCentralWidget(centralWidget) self.notifier = None # Set by main script # Initialise a thread pool self.threadPool = QThreadPool.globalInstance() logging.info('Multithreading with maximum {} threads'.format( self.threadPool.maxThreadCount())) self.setWindowTitle('dataMole') self.setUpMenus() self.__spinnerMutex = QMutex() centralWidget.frameInfoPanel.operationRequest.connect( self.executeOperation) centralWidget.workbenchView.selectedRowChanged[str, str].connect( self.changedSelectedFrame)
def __init__(self, mainWindow=None, name="", goalPosition=0, status=False): """ Initialization :param mainWindow: The main window of the ui :param name: The name of the motor :param pos: The position of the motor :param status: the status of the motor """ ## The main window of the ui self.__name = name ## The goal position of the motor self.__goalPosition = goalPosition ## The current position of the motor self.__currentPosition = 0 ## The status of the motor self.__status = status ## The main window of the ui self.__window = mainWindow self.mu = QMutex()
def __init__(self, history_time_s=1.0): self.mutex = QMutex() self.history_time_ns = np.int64(history_time_s * 1e9) self.times = np.zeros((0, ), dtype=np.int64) self.gas = np.zeros((0, ), dtype=np.uint16) self.brake = np.zeros((0, ), dtype=np.uint16) self.clutch = np.zeros((0, ), dtype=np.uint16) self.sx = np.zeros((0, ), dtype=np.uint16) self.sy = np.zeros((0, ), dtype=np.uint16) self.calib = CalibData()
class QIpScanner(QObject): networkIpReceived = Signal(str, str, str) def __init__(self, parent=None): super().__init__(parent) self.isScanning = False self.worker = _Worker(self.networkIpReceived, self) self.mutex = QMutex() @Slot(result=bool) def isRunning(self): return self.worker.isRunning() @Slot() def scan(self): self.mutex.lock() if not self.worker.isRunning(): self.worker.start() self.mutex.unlock()
def __init__(self, parent=None): super(DetailViewer, self).__init__(parent) self.ui = detailViewer_ui.Ui_MainWindow() self.ui.setupUi(self) self.__deviceModel = DeviceModel(self) self.__folderModel = FolderModel(self) self.ui.deviceTreeView.setModel(self.__deviceModel) self.ui.folderTreeView.setModel(self.__folderModel) self.__deviceEventCatched = ServerEventCatcher( [sth.DevicesConfigurationEvent]) self.__deviceEventCatched.event_arrived.connect(self.process_event) self.__folderEventCatched = ServerEventCatcher( [sth.FoldersConfigurationEvent]) self.__folderEventCatched.event_arrived.connect(self.process_event) self.__setterMutex = QMutex() self.__server = None
def __init__(self, name, parentPropColl, loadedFromConfig=None): PropertyCollection.__init__(self) assertMainThread() self._properties = {} self._accessed = False # if no access to properties has been made, we stick with configs from config file. self._loadedFromConfig = loadedFromConfig if loadedFromConfig is not None else {} self._propertyMutex = QMutex(QMutex.Recursive) if parentPropColl is not None: if not isinstance(parentPropColl, PropertyCollectionImpl): raise NexTInternalError("parentPropColl should always be a property collection instance but it isn't") parentPropColl.addChild(name, self)
def __init__(self, parent: QWidget = None, frame: Union[Frame, Shape] = Frame()): super().__init__(parent) if isinstance(frame, Frame): self.__frame: Frame = frame self.__shape: Shape = self.__frame.shape elif isinstance(frame, Shape): # it's a Shape self.__frame: Frame = Frame() self.__shape: Shape = frame else: self.__frame: Frame = Frame() self.__shape: Shape = Shape() # Dictionary { attributeIndex: value } self._statistics: Dict[int, Dict[str, object]] = dict() self._histogram: Dict[int, Dict[Any, int]] = dict() # Dataframe name self.name: str = '' # Set of alive workers by identifier (attribute number, type, operation) self._runningWorkers: Set[Tuple] = set() self._dataAccessMutex = QMutex()
class SingleRunnableManager(QObject): def __init__(self, thread_pool: QThreadPool): """ Runs a runnable on a thread pool, canceling the previous runnable if it is still enqueued. Parameters ---------- thread_pool The thread pool that will be used to run the runnable. """ super().__init__() self._thread_pool = thread_pool self._current_runnable = None self._lock = QMutex() def remove_runnable(self) -> None: """ Removes the current runnable without canceling its execution. """ self._lock.lock() try: del self._current_runnable self._current_runnable = None gc.collect() finally: self._lock.unlock() def _cancel(self) -> None: if self._current_runnable is not None: self._thread_pool.cancel(self._current_runnable) del self._current_runnable self._current_runnable = None gc.collect() def start(self, runnable: QRunnable) -> None: """ Cancel the current runnable (if any) and enqueue the runnable for execution on the thread pool. Parameters ---------- runnable The runnable to run """ self._lock.lock() try: self._cancel() self._thread_pool.start(runnable) finally: self._lock.unlock()
def __init__(self, library, factoryFunction, propertyCollection, mockup=None): BaseFilterEnvironment.__init__(self, propertyCollection) # ports are accessed by multiple threads (from FilterMockup.createFilter) self._portMutex = QMutex(QMutex.Recursive) self._ports = [] self._mockup = mockup self._state = FilterState.CONSTRUCTING if library is not None: plugin = PluginManager.singleton().create(library, factoryFunction, self) if plugin is not None: self.setPlugin(plugin) plugin.setObjectName(str(library) + "_" + str(factoryFunction)) self._state = FilterState.CONSTRUCTED
class USBWriteThread(QThread): mutex = QMutex() def __init__(self, device, tx_data): QThread.__init__(self) self.device = device self.tx_data = tx_data self.num_bytes_written = 0 def run(self, *args, **kwargs): self.mutex.lock() self.num_bytes_written = self.device.write(self.tx_data) # print "write thread:", self.num_bytes_written, self.tx_data.encode('hex') self.mutex.unlock()
def test_dark_current_compensated(empty_settings, preamble, raw_data_without_pump): """Ensure that dark current is subtracted from the raw signals. The dummy preamble is populated with signals around 1.0, so we subtract a dark current of 0.5 in order to be able to very clearl distinguish when the dark current has been subtracted. """ settings = empty_settings settings.dark_curr_par = 0.5 mutex = QMutex() worker = ComputationWorker(mutex, settings) worker.store_preamble(preamble) worker.compute_signals(raw_data_without_pump) assert worker.without_pump.par.mean() < 0.75
class ConfigWriter(QThread): config = None configSaved = Signal(object) mutex = QMutex() def __init__(self): super().__init__() self.cfg_file = Path.home() / 'Pythonic' / 'current_config.json' def saveConfig(self, config): self.mutex.lock() self.config = deepcopy(config) self.mutex.unlock() self.start() def run(self): logging.debug('ConfigWriter::saveConfig() called') self.mutex.lock() try: with open(self.cfg_file, 'w') as file: json.dump(self.config, file, indent=4) except Exception as e: logging.debug('ConfigWriter::saveConfig() - {}'.format(e)) pass return self.mutex.unlock() last_saved = "Config last saved: " + datetime.now().strftime( '%H:%M:%S') cmd = { 'cmd': 'SetInfoText', 'data': last_saved, 'address': { "target": "MainWindow" } } self.configSaved.emit(cmd)
def __init__(self, parent=None): super().__init__(parent) self.__mutex = QMutex() self.__laserFileList: list = None self.__rowMargin: int = 0 self.__laserFTPAddress: str = "" self.__laserFTPPort: int = 0 self.__laserFTPRemotePath: str = "" self.__cameraPath: str = "" self.__cameraSendCsv: bool = True self.__localWaitTimeBeforeStart: int = 1 self.__localLoadingPath: str = "" self.__localDownloadingPath: str = "" self.__csvFilename: str = "" self.__errorFilename: str = "" self.__logFilename: str = "" self.__stopRequest: bool = False self.__pauseRequest: bool = False self.__waitCondition = QWaitCondition()
class RenderThread(QThread): ColormapSize = 512 renderedImage = Signal(QImage, float) def __init__(self, parent=None): super(RenderThread, self).__init__(parent) self.mutex = QMutex() self.condition = QWaitCondition() self.centerX = 0.0 self.centerY = 0.0 self.scaleFactor = 0.0 self.resultSize = QSize() self.colormap = [] self.restart = False self.abort = False for i in range(RenderThread.ColormapSize): self.colormap.append(self.rgbFromWaveLength(380.0 + (i * 400.0 / RenderThread.ColormapSize))) def stop(self): self.mutex.lock() self.abort = True self.condition.wakeOne() self.mutex.unlock() self.wait(2000) def render(self, centerX, centerY, scaleFactor, resultSize): locker = QMutexLocker(self.mutex) self.centerX = centerX self.centerY = centerY self.scaleFactor = scaleFactor self.resultSize = resultSize if not self.isRunning(): self.start(QThread.LowPriority) else: self.restart = True self.condition.wakeOne() def run(self): while True: self.mutex.lock() resultSize = self.resultSize scaleFactor = self.scaleFactor centerX = self.centerX centerY = self.centerY self.mutex.unlock() halfWidth = resultSize.width() // 2 halfHeight = resultSize.height() // 2 image = QImage(resultSize, QImage.Format_RGB32) NumPasses = 8 curpass = 0 while curpass < NumPasses: MaxIterations = (1 << (2 * curpass + 6)) + 32 Limit = 4 allBlack = True for y in range(-halfHeight, halfHeight): if self.restart: break if self.abort: return ay = 1j * (centerY + (y * scaleFactor)) for x in range(-halfWidth, halfWidth): c0 = centerX + (x * scaleFactor) + ay c = c0 numIterations = 0 while numIterations < MaxIterations: numIterations += 1 c = c*c + c0 if abs(c) >= Limit: break numIterations += 1 c = c*c + c0 if abs(c) >= Limit: break numIterations += 1 c = c*c + c0 if abs(c) >= Limit: break numIterations += 1 c = c*c + c0 if abs(c) >= Limit: break if numIterations < MaxIterations: image.setPixel(x + halfWidth, y + halfHeight, self.colormap[numIterations % RenderThread.ColormapSize]) allBlack = False else: image.setPixel(x + halfWidth, y + halfHeight, qRgb(0, 0, 0)) if allBlack and curpass == 0: curpass = 4 else: if not self.restart: self.renderedImage.emit(image, scaleFactor) curpass += 1 self.mutex.lock() if not self.restart: self.condition.wait(self.mutex) self.restart = False self.mutex.unlock() def rgbFromWaveLength(self, wave): r = 0.0 g = 0.0 b = 0.0 if wave >= 380.0 and wave <= 440.0: r = -1.0 * (wave - 440.0) / (440.0 - 380.0) b = 1.0 elif wave >= 440.0 and wave <= 490.0: g = (wave - 440.0) / (490.0 - 440.0) b = 1.0 elif wave >= 490.0 and wave <= 510.0: g = 1.0 b = -1.0 * (wave - 510.0) / (510.0 - 490.0) elif wave >= 510.0 and wave <= 580.0: r = (wave - 510.0) / (580.0 - 510.0) g = 1.0 elif wave >= 580.0 and wave <= 645.0: r = 1.0 g = -1.0 * (wave - 645.0) / (645.0 - 580.0) elif wave >= 645.0 and wave <= 780.0: r = 1.0 s = 1.0 if wave > 700.0: s = 0.3 + 0.7 * (780.0 - wave) / (780.0 - 700.0) elif wave < 420.0: s = 0.3 + 0.7 * (wave - 380.0) / (420.0 - 380.0) r = pow(r * s, 0.8) g = pow(g * s, 0.8) b = pow(b * s, 0.8) return qRgb(r*255, g*255, b*255)
class msv2: def __init__(self): self.ser = serial.Serial() self.escape = 0 self.connected = 0 self.state = WAITING_DLE self.crc_data = [] self.data = [] self.mutex = QMutex() def explore(self): list = serial.tools.list_ports.comports(include_links=False) return [x.device for x in list] def connect(self, port): self.port = port self.ser.baudrate = BAUDRATE self.ser.port = port self.ser.timeout = 0.2 try: self.ser.open() self.connected = 1 print("connected") return 1 except: return 0 def reconnect(self): try: self.ser.port = self.port self.ser.baudrate = BAUDRATE self.ser.timeout = 0.2 self.ser.open() self.connected = 1 print("connected") return 1 except: return 0 def disconnect(self): try: self.ser.close() self.connected = 0 print("disconnected") return 1 except: return 0 def is_connected(self): return self.connected def encode(self, opcode, data): bin_data = [] crc_data = [] bin_data.append(DLE) bin_data.append(STX) bin_data.append(opcode) bin_data.append(int(len(data)/2)) crc_data.append(opcode) crc_data.append(int(len(data)/2)) i = 0 for byte in data: bin_data.append(byte) crc_data.append(byte) if byte == DLE: bin_data.append(byte) crc_data.append(0) crc_data.append(0) crc = crc16(crc_data) bin_data.append(crc & 0x00ff) bin_data.append((crc >> 8) & 0x00ff) return bin_data def decode(self, d): #print("decode state:", self.state) d = ord(d) if (self.escape == 1 and d == STX): self.state = WAITING_OPCODE self.escape = 0 return MSV2_PROGRESS if (self.state == WAITING_DLE and d == DLE): self.crc_data = [] self.data = [] self.state = WAITING_STX return MSV2_PROGRESS if (d == DLE and self.escape == 0): self.escape = 1 return MSV2_PROGRESS if (d == DLE and self.escape == 1): self.escape = 0 if (self.state == WAITING_STX and d == STX): self.state = WAITING_OPCODE return MSV2_PROGRESS if (self.state == WAITING_OPCODE): self.opcode = d self.state = WAITING_LEN self.crc_data.append(d) return MSV2_PROGRESS if (self.state == WAITING_LEN): self.data_len = d self.length = 2*d self.crc_data.append(d) self.counter = 0 self.state = WAITING_DATA return MSV2_PROGRESS if (self.state == WAITING_DATA): self.data.append(d) self.crc_data.append(d) self.counter += 1 if (self.counter==self.length): self.state = WAITING_CRC1 return MSV2_PROGRESS if (self.state == WAITING_CRC1): self.crc = d self.state = WAITING_CRC2 return MSV2_PROGRESS if (self.state == WAITING_CRC2): self.crc += d<<8 self.state = WAITING_DLE self.crc_data.append(0) self.crc_data.append(0) if(self.crc == crc16(self.crc_data)): return MSV2_SUCCESS else: return MSV2_WRONG_CRC self.state=WAITING_DLE return MSV2_PROGRESS def send(self, opcode, data): if self.connected: self.mutex.lock() msg = self.encode(opcode, data) error = 0 try: self.ser.write(msg) except: print("WRITE ERROR") self.mutex.unlock() self.reconnect() return -1 #print('[{}]'.format(', '.join(hex(x) for x in msg))) try: while 1: byte = self.ser.read(1) #print("dta: {}".format(hex(ord(byte)))) if not byte: print("no resp error") self.mutex.unlock() return 0 res = self.decode(byte) #print("res:", res) if not res == MSV2_PROGRESS: break #print('[{}]'.format(', '.join(hex(x) for x in self.data))) if self.data == [0xce, 0xec] or self.data == [0xbe, 0xeb]: self.mutex.unlock() print("CRC_ERROR") return 0 else: self.mutex.unlock() print("nominal_resp") return self.data except: print("READ ERROR") self.mutex.unlock() self.reconnect() return -1 else: print("CONN_ERROR") return -1
## included in the packaging of this file. Please review the following ## information to ensure the GNU General Public License requirements will ## be met: https://www.gnu.org/licenses/gpl-3.0.html. ## ## $QT_END_LICENSE$ ## ############################################################################# '''Test cases for QThread''' import unittest from PySide2.QtCore import QThread, QCoreApplication, QObject, SIGNAL, QMutex, QTimer from PySide2.QtCore import QEventLoop from helper import UsesQCoreApplication mutex = QMutex() class Dummy(QThread): '''Dummy thread''' def __init__(self, *args): super(Dummy, self).__init__(*args) self.called = False def run(self): #Start-quit sequence self.qobj = QObject() mutex.lock() self.called = True mutex.unlock()
class FortuneThread(QThread): newFortune = Signal(str) error = Signal(int, str) def __init__(self, parent=None): super(FortuneThread, self).__init__(parent) self.quit = False self.hostName = '' self.cond = QWaitCondition() self.mutex = QMutex() self.port = 0 def __del__(self): self.mutex.lock() self.quit = True self.cond.wakeOne() self.mutex.unlock() self.wait() def requestNewFortune(self, hostname, port): locker = QMutexLocker(self.mutex) self.hostName = hostname self.port = port if not self.isRunning(): self.start() else: self.cond.wakeOne() def run(self): self.mutex.lock() serverName = self.hostName serverPort = self.port self.mutex.unlock() while not self.quit: Timeout = 5 * 1000 socket = QTcpSocket() socket.connectToHost(serverName, serverPort) if not socket.waitForConnected(Timeout): self.error.emit(socket.error(), socket.errorString()) return while socket.bytesAvailable() < 2: if not socket.waitForReadyRead(Timeout): self.error.emit(socket.error(), socket.errorString()) return instr = QDataStream(socket) instr.setVersion(QDataStream.Qt_4_0) blockSize = instr.readUInt16() while socket.bytesAvailable() < blockSize: if not socket.waitForReadyRead(Timeout): self.error.emit(socket.error(), socket.errorString()) return self.mutex.lock() fortune = instr.readQString() self.newFortune.emit(fortune) self.cond.wait(self.mutex) serverName = self.hostName serverPort = self.port self.mutex.unlock()