def __init__(self, model): super().__init__() self._model = model layout = QGridLayout() splitter = QSplitter() self._bot_table = _BotTable() self._responses_tab = _ResponsesTab() self._execute_tab = _ExecuteTab(self._responses_tab, model) self._tab_widget = QTabWidget() self._tab_widget.addTab(self._execute_tab, "Execute") self._tab_widget.addTab(self._responses_tab, "Responses") splitter.setOrientation(Qt.Vertical) splitter.addWidget(self._bot_table) splitter.addWidget(self._tab_widget) splitter.setSizes([50, 100]) layout.addWidget(splitter) self.setLayout(layout) self._register_listeners()
def __init__(self, parent=None): super().__init__(parent) self.setWindowTitle('Direct tree') self.model = QFileSystemModel() self.model.setRootPath(QDir.rootPath()) self.tree = QTreeView() self.tree.setModel(self.model) self.tree.setRootIndex(self.model.index(os.getcwd())) self.tree.doubleClicked.connect(self._on_double_clicked) self.tree.setAnimated(False) self.tree.setIndentation(20) self.tree.setSortingEnabled(True) self.textEdit = QTextEdit() self.textEdit.setReadOnly(True) splitter = QSplitter() splitter.addWidget(self.tree) splitter.addWidget(self.textEdit) splitter.setSizes([50, 200]) self.setCentralWidget(splitter)
def init_workspace(self): splitter = QSplitter(self) splitter.setOrientation(Qt.Vertical) splitter.sizePolicy().setVerticalPolicy(QSizePolicy.Maximum) query_edit = self.init_query_text_edit() self.on_disconnected() splitter.addWidget(query_edit) results_widget = self.init_results_widget() splitter.addWidget(results_widget) splitter.setSizes([100, 900]) return splitter
def init_workspace(self): # Create a splitter consisting of query edit and table view splitter = QSplitter(self) splitter.setOrientation(Qt.Vertical) splitter.sizePolicy().setVerticalPolicy(QSizePolicy.Maximum) # Initialize query edit file query_edit = self.init_query_text_edit() # Disable query control buttons by default self.on_disconnected() splitter.addWidget(query_edit) # Initialize result desiplaying widgets results_widget = self.init_results_widget() splitter.addWidget(results_widget) splitter.setSizes([100, 900]) return splitter
class MainWindow(QWidget): def __init__(self, parent, imgDir): super(QWidget, self).__init__(parent) self.parent = parent self.imgDir = imgDir self.runInThread = ThreadFuns.runInThread ###-- Create clients and statuses self.hwdevice = None self.hwStatus = 0 self.hwStatusMess = "Not Connected" self.rpcClient = None self.rpcConnected = False self.rpcStatusMess = "Not Connected" ###-- Load icons & images self.loadIcons() ###-- Create main layout self.layout = QVBoxLayout() self.header = GuiHeader(self) self.initConsole() self.layout.addWidget(self.header) ###-- Create RPC Whatchdog self.rpc_watchdogThread = QThread() self.myRpcWd = RpcWatchdog(self) self.myRpcWd.moveToThread(self.rpc_watchdogThread) self.rpc_watchdogThread.started.connect(self.myRpcWd.run) self.rpc_watchdogThread.start() ###-- Create Queues and redirect stdout and stderr (eventually) self.queue = Queue() self.queue2 = Queue() sys.stdout = WriteStream(self.queue) sys.stderr = WriteStream(self.queue2) ###-- Init last logs logFile = open(log_File, 'w+') timestamp = strftime('%Y-%m-%d %H:%M:%S', gmtime(now())) log_line = '<b style="color: blue">{}</b><br>'.format( 'STARTING PET4L at ' + timestamp) logFile.write(log_line) logFile.close() ###-- Create the thread to update console log for stdout self.consoleLogThread = QThread() self.myWSReceiver = WriteStreamReceiver(self.queue) self.myWSReceiver.mysignal.connect(self.append_to_console) self.myWSReceiver.moveToThread(self.consoleLogThread) self.consoleLogThread.started.connect(self.myWSReceiver.run) self.consoleLogThread.start() printDbg("Console Log thread started") ###-- Create the thread to update console log for stderr self.consoleLogThread2 = QThread() self.myWSReceiver2 = WriteStreamReceiver(self.queue2) self.myWSReceiver2.mysignal.connect(self.append_to_console) self.myWSReceiver2.moveToThread(self.consoleLogThread2) self.consoleLogThread2.started.connect(self.myWSReceiver2.run) self.consoleLogThread2.start() printDbg("Console Log thread 2 started") ###-- Initialize tabs self.tabs = QTabWidget() self.t_rewards = TabRewards(self) ###-- Add tabs self.tabs.addTab(self.tabRewards, "Spend from Ledger") ###-- Draw Tabs self.splitter = QSplitter(Qt.Vertical) ###-- Add tabs and console to Layout self.splitter.addWidget(self.tabs) self.splitter.addWidget(self.console) self.splitter.setStretchFactor(0, 0) self.splitter.setStretchFactor(1, 1) self.splitter.setSizes([2, 1]) self.layout.addWidget(self.splitter) ###-- Set Layout self.setLayout(self.layout) ###-- Let's go self.mnode_to_change = None printOK("Hello! Welcome to " + parent.title) @pyqtSlot(str) def append_to_console(self, text): self.consoleArea.moveCursor(QTextCursor.End) self.consoleArea.insertHtml(text) # update last logs logFile = open(log_File, 'a+') logFile.write(text) logFile.close() def initConsole(self): self.console = QGroupBox() self.console.setTitle("Console Log") layout = QVBoxLayout() self.btn_consoleToggle = QPushButton('Hide') self.btn_consoleToggle.setToolTip('Show/Hide console') self.btn_consoleToggle.clicked.connect(lambda: self.onToggleConsole()) consoleHeader = QHBoxLayout() consoleHeader.addWidget(self.btn_consoleToggle) self.consoleSaveButton = QPushButton('Save') self.consoleSaveButton.clicked.connect(lambda: self.onSaveConsole()) consoleHeader.addWidget(self.consoleSaveButton) self.btn_consoleClean = QPushButton('Clean') self.btn_consoleClean.setToolTip('Clean console log area') self.btn_consoleClean.clicked.connect(lambda: self.onCleanConsole()) consoleHeader.addWidget(self.btn_consoleClean) consoleHeader.addStretch(1) layout.addLayout(consoleHeader) self.consoleArea = QTextEdit() almostBlack = QColor(40, 40, 40) palette = QPalette() palette.setColor(QPalette.Base, almostBlack) green = QColor(0, 255, 0) palette.setColor(QPalette.Text, green) self.consoleArea.setPalette(palette) layout.addWidget(self.consoleArea) self.console.setLayout(layout) def loadIcons(self): # Load Icons self.ledPurpleH_icon = QPixmap( os.path.join(self.imgDir, 'icon_purpleLedH.png')).scaledToHeight( 17, Qt.SmoothTransformation) self.ledGrayH_icon = QPixmap( os.path.join(self.imgDir, 'icon_grayLedH.png')).scaledToHeight( 17, Qt.SmoothTransformation) self.ledHalfPurpleH_icon = QPixmap( os.path.join(self.imgDir, 'icon_halfPurpleLedH.png')).scaledToHeight( 17, Qt.SmoothTransformation) self.ledRedV_icon = QPixmap( os.path.join(self.imgDir, 'icon_redLedV.png')).scaledToHeight( 17, Qt.SmoothTransformation) self.ledGrayV_icon = QPixmap( os.path.join(self.imgDir, 'icon_grayLedV.png')).scaledToHeight( 17, Qt.SmoothTransformation) self.ledGreenV_icon = QPixmap( os.path.join(self.imgDir, 'icon_greenLedV.png')).scaledToHeight( 17, Qt.SmoothTransformation) self.ledgerImg = QPixmap(os.path.join(self.imgDir, 'ledger.png')) def myPopUp(self, messType, messTitle, messText, defaultButton=QMessageBox.No): mess = QMessageBox(messType, messTitle, messText, defaultButton, parent=self) mess.setStandardButtons(QMessageBox.Yes | QMessageBox.No) mess.setDefaultButton(defaultButton) return mess.exec_() def myPopUp2(self, messType, messTitle, messText, singleButton=QMessageBox.Ok): mess = QMessageBox(messType, messTitle, messText, singleButton, parent=self) mess.setStandardButtons(singleButton | singleButton) return mess.exec_() @pyqtSlot() def onCheckHw(self): printDbg("Checking for HW device...") self.runInThread(self.updateHWstatus, (), self.showHWstatus) @pyqtSlot() def onCheckRpc(self): printDbg("Checking RPC server...") self.runInThread(self.updateRPCstatus, (), self.showRPCstatus) @pyqtSlot() def onCleanConsole(self): self.consoleArea.clear() @pyqtSlot() def onSaveConsole(self): timestamp = strftime('%Y-%m-%d_%H-%M-%S', gmtime(now())) options = QFileDialog.Options() options |= QFileDialog.DontUseNativeDialog fileName, _ = QFileDialog.getSaveFileName( self, "Save Logs to file", "PET4L_Logs_%s.txt" % timestamp, "All Files (*);; Text Files (*.txt)", options=options) try: if fileName: printOK("Saving logs to %s" % fileName) log_file = open(fileName, 'w+') log_text = self.consoleArea.toPlainText() log_file.write(log_text) log_file.close() except Exception as e: err_msg = "error writing Log file" printException(getCallerName(), getFunctionName(), err_msg, e.args) @pyqtSlot() def onToggleConsole(self): if self.btn_consoleToggle.text() == 'Hide': self.btn_consoleToggle.setText('Show') self.consoleArea.hide() self.previousH = self.splitter.sizes()[1] self.console.setMaximumHeight(70) else: self.console.setMinimumHeight(self.previousH) self.console.setMaximumHeight(starting_height) self.btn_consoleToggle.setText('Hide') self.consoleArea.show() def showHWstatus(self): self.updateHWleds() self.myPopUp2(QMessageBox.Information, 'PET4L - hw check', "STATUS: %s" % self.hwStatusMess, QMessageBox.Ok) def showRPCstatus(self): self.updateRPCled() self.myPopUp2(QMessageBox.Information, 'PET4L - rpc check', "STATUS: %s" % self.rpcStatusMess, QMessageBox.Ok) def updateHWleds(self): if self.hwStatus == 1: self.header.hwLed.setPixmap(self.ledHalfPurpleH_icon) elif self.hwStatus == 2: self.header.hwLed.setPixmap(self.ledPurpleH_icon) else: self.header.hwLed.setPixmap(self.ledGrayH_icon) self.header.hwLed.setToolTip(self.hwStatusMess) def updateHWstatus(self, ctrl): if self.hwdevice is None: self.hwdevice = HWdevice() device = self.hwdevice statusCode = device.getStatusCode() statusMess = device.getStatusMess(statusCode) printDbg("code: %s - mess: %s" % (statusCode, statusMess)) if statusCode != 2: try: if getattr(self.hwdevice, 'dongle', None) is not None: self.hwdevice.dongle.close() self.hwdevice.initDevice() device = self.hwdevice statusCode = device.getStatusCode() statusMess = device.getStatusMess(statusCode) except Exception as e: err_msg = "error in checkHw" printException(getCallerName(), getFunctionName(), err_msg, e.args) self.hwStatus = statusCode self.hwStatusMess = statusMess def updateLastBlockLabel(self): text = '--' if self.rpcLastBlock == 1: text = "Loading block index..." elif self.rpcLastBlock > 0 and self.rpcConnected: text = str(self.rpcLastBlock) self.header.lastBlockLabel.setText(text) def updateRPCled(self): if self.rpcConnected: self.header.rpcLed.setPixmap(self.ledPurpleH_icon) else: if self.rpcLastBlock == 1: self.header.rpcLed.setPixmap(self.ledHalfPurpleH_icon) else: self.header.rpcLed.setPixmap(self.ledGrayH_icon) self.header.rpcLed.setToolTip(self.rpcStatusMess) self.updateLastBlockLabel() def updateRPCstatus(self, ctrl): if self.rpcClient is None: try: self.rpcClient = RpcClient() except Exception as e: print(e) status, lastBlock = self.rpcClient.getStatus() statusMess = self.rpcClient.getStatusMess(status) if not status and lastBlock == 0: try: self.rpcClient = RpcClient() status, lastBlock = self.rpcClient.getStatus() statusMess = self.rpcClient.getStatusMess(status) except Exception as e: err_msg = "error in checkRpc" printException(getCallerName(), getFunctionName(), err_msg, e) elif lastBlock == 1: statusMess = "PIVX wallet is connected but still synchronizing / verifying blocks" self.rpcConnected = status self.rpcLastBlock = lastBlock self.rpcStatusMess = statusMess
class MainWindow(QWidget): def __init__(self, parent, masternode_list, imgDir): super(QWidget, self).__init__(parent) self.parent = parent self.imgDir = imgDir self.runInThread = ThreadFuns.runInThread ###-- Masternode list self.masternode_list = masternode_list ###-- Create clients and statuses self.hwdevice = None self.hwStatus = 0 self.hwStatusMess = "Not Connected" self.rpcClient = None self.rpcConnected = False self.rpcStatusMess = "Not Connected" self.isBlockchainSynced = False ###-- Load icons & images self.loadIcons() ###-- Create main layout self.layout = QVBoxLayout() self.header = GuiHeader(self) self.initConsole() self.layout.addWidget(self.header) ###-- Create RPC Whatchdog self.rpc_watchdogThread = QThread() self.myRpcWd = RpcWatchdog(self) self.myRpcWd.moveToThread(self.rpc_watchdogThread) self.rpc_watchdogThread.started.connect(self.myRpcWd.run) self.rpc_watchdogThread.start() ###-- Create Queues and redirect stdout and stderr (eventually) self.queue = Queue() self.queue2 = Queue() sys.stdout = WriteStream(self.queue) sys.stderr = WriteStream(self.queue2) ###-- Init last logs logFile = open(log_File, 'w+') timestamp = strftime('%Y-%m-%d %H:%M:%S', gmtime(now())) log_line = '<b style="color: blue">{}</b><br>'.format('STARTING SPMT at '+ timestamp) logFile.write(log_line) logFile.close() ###-- Create the thread to update console log for stdout self.consoleLogThread = QThread() self.myWSReceiver = WriteStreamReceiver(self.queue) self.myWSReceiver.mysignal.connect(self.append_to_console) self.myWSReceiver.moveToThread(self.consoleLogThread) self.consoleLogThread.started.connect(self.myWSReceiver.run) self.consoleLogThread.start() printDbg("Console Log thread started") ###-- Create the thread to update console log for stderr self.consoleLogThread2 = QThread() self.myWSReceiver2 = WriteStreamReceiver(self.queue2) self.myWSReceiver2.mysignal.connect(self.append_to_console) self.myWSReceiver2.moveToThread(self.consoleLogThread2) self.consoleLogThread2.started.connect(self.myWSReceiver2.run) self.consoleLogThread2.start() printDbg("Console Log thread 2 started") ###-- Initialize tabs self.tabs = QTabWidget() self.t_main = TabMain(self) self.t_mnconf = TabMNConf(self) self.t_rewards = TabRewards(self) ###-- Add tabs self.tabs.addTab(self.tabMain, "Masternode Control") #self.tabs.addTab(self.tabMNConf, "MN Configuration") self.tabs.addTab(self.tabRewards, "Transfer Rewards") ###-- Connect change action self.tabs.currentChanged.connect(lambda: self.onTabChange()) ###-- Draw Tabs self.splitter = QSplitter(Qt.Vertical) ###-- Add tabs and console to Layout self.splitter.addWidget(self.tabs) self.splitter.addWidget(self.console) self.splitter.setStretchFactor(0,0) self.splitter.setStretchFactor(1,1) self.splitter.setSizes(self.parent.cache.get("splitter_sizes")) self.layout.addWidget(self.splitter) ###-- Set Layout self.setLayout(self.layout) ###-- Let's go self.mnode_to_change = None printOK("Hello! Welcome to " + parent.title) ###-- Hide console if it was previously hidden if self.parent.cache.get("console_hidden"): self.onToggleConsole() ##-- Check version self.onCheckVersion() @pyqtSlot(str) def append_to_console(self, text): self.consoleArea.moveCursor(QTextCursor.End) self.consoleArea.insertHtml(text) # update last logs logFile = open(log_File, 'a+') logFile.write(text) logFile.close() def initConsole(self): self.console = QGroupBox() self.console.setTitle("Console Log") layout = QVBoxLayout() self.btn_consoleToggle = QPushButton('Hide') self.btn_consoleToggle.setToolTip('Show/Hide console') self.btn_consoleToggle.clicked.connect(lambda: self.onToggleConsole()) consoleHeader = QHBoxLayout() consoleHeader.addWidget(self.btn_consoleToggle) self.consoleSaveButton = QPushButton('Save') self.consoleSaveButton.clicked.connect(lambda: self.onSaveConsole()) consoleHeader.addWidget(self.consoleSaveButton) self.btn_consoleClean = QPushButton('Clean') self.btn_consoleClean.setToolTip('Clean console log area') self.btn_consoleClean.clicked.connect(lambda: self.onCleanConsole()) consoleHeader.addWidget(self.btn_consoleClean) consoleHeader.addStretch(1) self.versionLabel = QLabel("--") self.versionLabel.setOpenExternalLinks(True) consoleHeader.addWidget(self.versionLabel) self.btn_checkVersion = QPushButton("Check SPMT version") self.btn_checkVersion.setToolTip("Check latest stable release of SPMT") self.btn_checkVersion.clicked.connect(lambda: self.onCheckVersion()) consoleHeader.addWidget(self.btn_checkVersion) layout.addLayout(consoleHeader) self.consoleArea = QTextEdit() almostBlack = QColor(40, 40, 40) palette = QPalette() palette.setColor(QPalette.Base, almostBlack) green = QColor(0, 255, 0) palette.setColor(QPalette.Text, green) self.consoleArea.setPalette(palette) layout.addWidget(self.consoleArea) self.console.setLayout(layout) def loadIcons(self): # Load Icons self.ledPurpleH_icon = QPixmap(os.path.join(self.imgDir, 'icon_purpleLedH.png')).scaledToHeight(17, Qt.SmoothTransformation) self.ledGrayH_icon = QPixmap(os.path.join(self.imgDir, 'icon_grayLedH.png')).scaledToHeight(17, Qt.SmoothTransformation) self.ledHalfPurpleH_icon = QPixmap(os.path.join(self.imgDir, 'icon_halfPurpleLedH.png')).scaledToHeight(17, Qt.SmoothTransformation) self.ledRedV_icon = QPixmap(os.path.join(self.imgDir, 'icon_redLedV.png')).scaledToHeight(17, Qt.SmoothTransformation) self.ledGrayV_icon = QPixmap(os.path.join(self.imgDir, 'icon_grayLedV.png')).scaledToHeight(17, Qt.SmoothTransformation) self.ledGreenV_icon = QPixmap(os.path.join(self.imgDir, 'icon_greenLedV.png')).scaledToHeight(17, Qt.SmoothTransformation) def myPopUp(self, messType, messTitle, messText, defaultButton=QMessageBox.No): mess = QMessageBox(messType, messTitle, messText, defaultButton, parent=self) mess.setStandardButtons(QMessageBox.Yes | QMessageBox.No) mess.setDefaultButton(defaultButton) return mess.exec_() def myPopUp2(self, messType, messTitle, messText, singleButton=QMessageBox.Ok): mess = QMessageBox(messType, messTitle, messText, singleButton, parent=self) mess.setStandardButtons(singleButton | singleButton) return mess.exec_() @pyqtSlot() def onCheckHw(self): printDbg("Checking for HW device...") self.updateHWstatus(None) self.showHWstatus() @pyqtSlot() def onCheckRpc(self): printDbg("Checking RPC server...") self.runInThread(self.updateRPCstatus, (), self.showRPCstatus) @pyqtSlot() def onCheckVersion(self): printDbg("Checking SPMT version...") self.versionLabel.setText("--") self.runInThread(self.checkVersion, (), self.updateVersion) def checkVersion(self, ctrl): local_version = self.parent.version['number'].split('.') remote_version = getRemoteSPMTversion().split('.') if (remote_version[0] > local_version[0]) or \ (remote_version[0] == local_version[0] and remote_version[1] > local_version[1]) or \ (remote_version[0] == local_version[0] and remote_version[1] == local_version[1] and remote_version[2] > local_version[2]): self.versionMess = '<b style="color:red">New Version Available:</b> %s.%s.%s ' % (remote_version[0], remote_version[1], remote_version[2]) self.versionMess += '(<a href="https://github.com/PIVX-Project/PIVX-SPMT/releases/">download</a>)' else: self.versionMess = "You have the latest version of SPMT" def updateVersion(self): if self.versionMess is not None: self.versionLabel.setText(self.versionMess) @pyqtSlot() def onCleanConsole(self): self.consoleArea.clear() @pyqtSlot() def onSaveConsole(self): timestamp = strftime('%Y-%m-%d_%H-%M-%S', gmtime(now())) options = QFileDialog.Options() options |= QFileDialog.DontUseNativeDialog fileName, _ = QFileDialog.getSaveFileName(self,"Save Logs to file","SPMT_Logs_%s.txt" % timestamp,"All Files (*);; Text Files (*.txt)", options=options) try: if fileName: printOK("Saving logs to %s" % fileName) log_file = open(fileName, 'w+') log_text = self.consoleArea.toPlainText() log_file.write(log_text) log_file.close() except Exception as e: err_msg = "error writing Log file" printException(getCallerName(), getFunctionName(), err_msg, e.args) @pyqtSlot() def onTabChange(self): # reload (and re-sort)masternode list in tabs if self.tabs.currentWidget() == self.tabRewards: # reload last used address self.tabRewards.destinationLine.setText(self.parent.cache.get("lastAddress")) # get new order mnOrder = {} mnList = self.tabMain.myList for i in range(mnList.count()): mnName = mnList.itemWidget(mnList.item(i)).alias mnOrder[mnName] = i self.parent.cache['mnList_order'] = mnOrder # Sort masternode list (by alias if no previous order set) if self.parent.cache.get('mnList_order') != {}: self.masternode_list.sort(key=self.parent.extract_order) self.t_rewards.loadMnSelect() self.t_rewards.selectedRewards = None @pyqtSlot() def onToggleConsole(self): if self.btn_consoleToggle.text() == 'Hide': self.btn_consoleToggle.setText('Show') self.consoleArea.hide() self.console.setMinimumHeight(70) self.console.setMaximumHeight(70) else: self.console.setMinimumHeight(70) self.console.setMaximumHeight(starting_height) self.btn_consoleToggle.setText('Hide') self.consoleArea.show() def showHWstatus(self): self.updateHWleds() self.myPopUp2(QMessageBox.Information, 'SPMT - hw check', "%s" % self.hwStatusMess, QMessageBox.Ok) def showRPCstatus(self): self.updateRPCled() self.myPopUp2(QMessageBox.Information, 'SPMT - rpc check', "%s" % self.rpcStatusMess, QMessageBox.Ok) def updateHWleds(self): if self.hwStatus == 1: self.header.hwLed.setPixmap(self.ledHalfPurpleH_icon) elif self.hwStatus == 2: self.header.hwLed.setPixmap(self.ledPurpleH_icon) else: self.header.hwLed.setPixmap(self.ledGrayH_icon) self.header.hwLed.setToolTip(self.hwStatusMess) def updateHWstatus(self, ctrl): if self.hwdevice is None: self.hwdevice = HWdevice() device = self.hwdevice statusCode = device.getStatusCode() statusMess = device.getStatusMess(statusCode) printDbg("code: %s - mess: %s" % (statusCode, statusMess)) if statusCode != 2: try: if getattr(self.hwdevice, 'dongle', None) is not None: self.hwdevice.dongle.close() self.hwdevice.initDevice() device = self.hwdevice statusCode = device.getStatusCode() statusMess = device.getStatusMess(statusCode) except Exception as e: err_msg = "error in checkHw" printException(getCallerName(), getFunctionName(), err_msg, e.args) self.hwStatus = statusCode self.hwStatusMess = statusMess def updateLastBlockLabel(self): text = '--' if self.rpcLastBlock == 1: text = "Loading block index..." elif self.rpcLastBlock > 0 and self.rpcConnected: text = str(self.rpcLastBlock) text += " (" if not self.isBlockchainSynced: text += "Synchronizing" else: text += "Synced" text += ")" self.header.lastBlockLabel.setText(text) def updateRPCled(self): if self.rpcConnected: self.header.rpcLed.setPixmap(self.ledPurpleH_icon) else: if self.rpcLastBlock == 1: self.header.rpcLed.setPixmap(self.ledHalfPurpleH_icon) else: self.header.rpcLed.setPixmap(self.ledGrayH_icon) self.header.rpcLed.setToolTip(self.rpcStatusMess) self.updateLastBlockLabel() def updateRPCstatus(self, ctrl): if self.rpcClient is None: try: self.rpcClient = RpcClient() except Exception as e: print(e) status, lastBlock = self.rpcClient.getStatus() statusMess = self.rpcClient.getStatusMess(status) if not status and lastBlock==0: try: self.rpcClient = RpcClient() status, lastBlock = self.rpcClient.getStatus() statusMess = self.rpcClient.getStatusMess(status) except Exception as e: err_msg = "error in checkRpc" printException(getCallerName(), getFunctionName(), err_msg, e) elif lastBlock == 1: statusMess = "PIVX wallet is connected but still synchronizing / verifying blocks" self.rpcConnected = status self.rpcLastBlock = lastBlock self.rpcStatusMess = statusMess self.isBlockchainSynced = self.rpcClient.isBlockchainSynced()
class MainWindow(QWidget): def __init__(self, parent, masternode_list, imgDir): super(QWidget, self).__init__(parent) self.parent = parent self.imgDir = imgDir self.runInThread = ThreadFuns.runInThread ###-- Masternode list self.masternode_list = masternode_list ###-- Create clients and statuses self.hwdevice = None self.hwStatus = 0 self.hwStatusMess = "Not Connected" self.rpcClient = None self.rpcConnected = False self.rpcStatusMess = "Not Connected" self.isBlockchainSynced = False ###-- Load icons & images self.loadIcons() ###-- Create main layout self.layout = QVBoxLayout() self.header = GuiHeader(self) self.initConsole() self.layout.addWidget(self.header) ###-- Create RPC Whatchdog self.rpc_watchdogThread = QThread() self.myRpcWd = RpcWatchdog(self) self.myRpcWd.moveToThread(self.rpc_watchdogThread) self.rpc_watchdogThread.started.connect(self.myRpcWd.run) ###-- Create Queues and redirect stdout and stderr self.queue = Queue() self.queue2 = Queue() sys.stdout = WriteStream(self.queue) sys.stderr = WriteStream(self.queue2) ###-- Init last logs logFile = open(log_File, 'w+') timestamp = strftime('%Y-%m-%d %H:%M:%S', gmtime(now())) log_line = '<b style="color: blue">{}</b><br>'.format('STARTING QMT at ' + timestamp) logFile.write(log_line) logFile.close() ###-- Create the thread to update console log for stdout self.consoleLogThread = QThread() self.myWSReceiver = WriteStreamReceiver(self.queue) self.myWSReceiver.mysignal.connect(self.append_to_console) self.myWSReceiver.moveToThread(self.consoleLogThread) self.consoleLogThread.started.connect(self.myWSReceiver.run) self.consoleLogThread.start() printDbg("Console Log thread started") ###-- Create the thread to update console log for stderr self.consoleLogThread2 = QThread() self.myWSReceiver2 = WriteStreamReceiver(self.queue2) self.myWSReceiver2.mysignal.connect(self.append_to_console) self.myWSReceiver2.moveToThread(self.consoleLogThread2) self.consoleLogThread2.started.connect(self.myWSReceiver2.run) self.consoleLogThread2.start() printDbg("Console Log thread 2 started") ###-- Initialize tabs self.tabs = QTabWidget() self.t_main = TabMain(self) self.t_mnconf = TabMNConf(self) self.t_rewards = TabRewards(self) self.t_governance = TabGovernance(self) self.t_add_torrent = TabAddTorrent(self) ###-- Add tabs self.tabs.addTab(self.tabGovernance, "Search Torrents") self.tabs.addTab(self.tabAddTorrent, "Add Torrents") # self.tabs.addTab(self.tabMain, "Masternode Control") # self.tabs.addTab(self.tabMNConf, "MN Configuration") # We will put these back later, just with RPC instead of messy key handling which we don't need or want anyway ! # self.tabs.addTab(self.tabRewards, "Transfer Rewards") ###-- Connect change action self.tabs.currentChanged.connect(lambda: self.onTabChange()) ###-- Draw Tabs self.splitter = QSplitter(Qt.Vertical) ###-- Add tabs and console to Layout self.splitter.addWidget(self.tabs) self.splitter.addWidget(self.console) self.splitter.setStretchFactor(0, 0) self.splitter.setStretchFactor(1, 1) self.splitter.setSizes(self.parent.cache.get("splitter_sizes")) self.layout.addWidget(self.splitter) ###-- Set Layout self.setLayout(self.layout) ###-- Let's go self.mnode_to_change = None printOK("Hello! Welcome to " + parent.title) ###-- Hide console if it was previously hidden if self.parent.cache.get("console_hidden"): self.onToggleConsole() ##-- Check version self.onCheckVersion() ##-- init Api Client self.apiClient = ApiClient() @pyqtSlot(str) def append_to_console(self, text): self.consoleArea.moveCursor(QTextCursor.End) self.consoleArea.insertHtml(text) def initConsole(self): self.console = QGroupBox() self.console.setTitle("Console Log") layout = QVBoxLayout() self.btn_consoleToggle = QPushButton('Hide') self.btn_consoleToggle.setToolTip('Show/Hide console') self.btn_consoleToggle.clicked.connect(lambda: self.onToggleConsole()) consoleHeader = QHBoxLayout() consoleHeader.addWidget(self.btn_consoleToggle) self.consoleSaveButton = QPushButton('Save') self.consoleSaveButton.clicked.connect(lambda: self.onSaveConsole()) consoleHeader.addWidget(self.consoleSaveButton) self.btn_consoleClean = QPushButton('Clean') self.btn_consoleClean.setToolTip('Clean console log area') self.btn_consoleClean.clicked.connect(lambda: self.onCleanConsole()) consoleHeader.addWidget(self.btn_consoleClean) consoleHeader.addStretch(1) self.versionLabel = QLabel("--") self.versionLabel.setOpenExternalLinks(True) consoleHeader.addWidget(self.versionLabel) self.btn_checkVersion = QPushButton("Check QMT version") self.btn_checkVersion.setToolTip("Check latest stable release of QMT") self.btn_checkVersion.clicked.connect(lambda: self.onCheckVersion()) consoleHeader.addWidget(self.btn_checkVersion) layout.addLayout(consoleHeader) self.consoleArea = QTextEdit() almostBlack = QColor(40, 40, 40) palette = QPalette() palette.setColor(QPalette.Base, almostBlack) green = QColor(0, 255, 0) palette.setColor(QPalette.Text, green) self.consoleArea.setPalette(palette) layout.addWidget(self.consoleArea) self.console.setLayout(layout) def isMasternodeInList(self, mn_alias): return (mn_alias in [x['name'] for x in self.masternode_list]) def loadIcons(self): # Load Icons self.ledPurpleH_icon = QPixmap(os.path.join(self.imgDir, 'icon_purpleLedH.png')).scaledToHeight(17, Qt.SmoothTransformation) self.ledGrayH_icon = QPixmap(os.path.join(self.imgDir, 'icon_grayLedH.png')).scaledToHeight(17, Qt.SmoothTransformation) self.ledHalfPurpleH_icon = QPixmap(os.path.join(self.imgDir, 'icon_halfPurpleLedH.png')).scaledToHeight(17, Qt.SmoothTransformation) self.ledRedV_icon = QPixmap(os.path.join(self.imgDir, 'icon_redLedV.png')).scaledToHeight(17, Qt.SmoothTransformation) self.ledGrayV_icon = QPixmap(os.path.join(self.imgDir, 'icon_grayLedV.png')).scaledToHeight(17, Qt.SmoothTransformation) self.ledGreenV_icon = QPixmap(os.path.join(self.imgDir, 'icon_greenLedV.png')).scaledToHeight(17, Qt.SmoothTransformation) def loadMNConf(self, fileName): hot_masternodes = loadMNConfFile(fileName) if hot_masternodes == None: messText = "Unable to load data from file '%s'" % fileName self.myPopUp2(QMessageBox.Warning, "QMT - warning", messText) else: # Append new masternodes to list new_masternodes = [] skip_masternodes = [] for x in hot_masternodes: if not self.isMasternodeInList(x['name']): self.masternode_list.append(x) new_masternodes.append(x) else: skip_masternodes.append(x) # Show new list for new_masternode in new_masternodes: name = new_masternode['name'] self.tabMain.insert_mn_list(name, new_masternode['ip'], new_masternode['port'], None, isHardware=False) self.tabMain.btn_remove[name].clicked.connect(lambda: self.t_main.onRemoveMN()) # print number of nodes added new_nodes = len(new_masternodes) final_message = "" if new_nodes == 0: final_message = "No External Masternode " elif new_nodes == 1: final_message = "1 External Masternode " else: final_message = "%d External Masternodes " % new_nodes final_message += "added to the list. " if new_nodes > 0: final_message += str([x['name'] for x in new_masternodes]) + ". " if len(skip_masternodes) > 0: final_message += "Following entries skipped due to duplicate names:" final_message += str([x['name'] for x in skip_masternodes]) + ". " printDbg(final_message) if new_nodes > 0: # update files printDbg("saving MN configuration file") writeToFile(self.masternode_list, masternodes_File) printDbg("saved") # Clear voting masternodes configuration and update cache self.t_governance.clear() def myPopUp(self, messType, messTitle, messText, defaultButton=QMessageBox.No): mess = QMessageBox(messType, messTitle, messText, defaultButton, parent=self) mess.setStandardButtons(QMessageBox.Yes | QMessageBox.No) mess.setDefaultButton(defaultButton) return mess.exec_() def myPopUp2(self, messType, messTitle, messText, singleButton=QMessageBox.Ok): mess = QMessageBox(messType, messTitle, messText, singleButton, parent=self) mess.setStandardButtons(singleButton | singleButton) return mess.exec_() @pyqtSlot() def onCheckHw(self): printDbg("Checking for HW device...") self.updateHWstatus(None) self.showHWstatus() @pyqtSlot() def onCheckRpc(self): printDbg("Checking RPC server...") self.runInThread(self.updateRPCstatus, (), self.showRPCstatus) @pyqtSlot() def onCheckVersion(self): printDbg("Checking QMT version...") self.versionLabel.setText("--") self.runInThread(self.checkVersion, (), self.updateVersion) def checkVersion(self, ctrl): local_version = self.parent.version['number'].split('.') remote_version = getRemoteQMTversion().split('.') if (remote_version[0] > local_version[0]) or \ (remote_version[0] == local_version[0] and remote_version[1] > local_version[1]) or \ (remote_version[0] == local_version[0] and remote_version[1] == local_version[1] and remote_version[2] > local_version[2]): self.versionMess = '<b style="color:red">New Version Available:</b> %s.%s.%s ' % ( remote_version[0], remote_version[1], remote_version[2]) self.versionMess += '(<a href="https://github.com/project-qmc/QMT/releases/">download</a>)' else: self.versionMess = "You have the latest version of QMT" def updateVersion(self): if self.versionMess is not None: self.versionLabel.setText(self.versionMess) @pyqtSlot() def onCleanConsole(self): self.consoleArea.clear() @pyqtSlot() def onSaveConsole(self): timestamp = strftime('%Y-%m-%d_%H-%M-%S', gmtime(now())) options = QFileDialog.Options() options |= QFileDialog.DontUseNativeDialog fileName, _ = QFileDialog.getSaveFileName(self, "Save Logs to file", "QMT_Logs_%s.txt" % timestamp, "All Files (*);; Text Files (*.txt)", options=options) try: if fileName: printOK("Saving logs to %s" % fileName) log_file = open(fileName, 'w+') log_text = self.consoleArea.toPlainText() log_file.write(log_text) log_file.close() except Exception as e: err_msg = "error writing Log file" printException(getCallerName(), getFunctionName(), err_msg, e.args) @pyqtSlot() def onTabChange(self): # reload (and re-sort)masternode list in tabs if self.tabs.currentWidget() == self.tabRewards: # reload last used address self.tabRewards.destinationLine.setText(self.parent.cache.get("lastAddress")) # get new order mnOrder = {} mnList = self.tabMain.myList for i in range(mnList.count()): mnName = mnList.itemWidget(mnList.item(i)).alias mnOrder[mnName] = i self.parent.cache['mnList_order'] = mnOrder # Sort masternode list (by alias if no previous order set) if self.parent.cache.get('mnList_order') != {}: self.masternode_list.sort(key=self.parent.extract_order) self.t_rewards.loadMnSelect() self.t_rewards.selectedRewards = None # reload torrent and voting masternode list if self.tabs.currentWidget() == self.tabGovernance: self.t_governance.onRefreshTorrents() self.t_governance.updateSelectedMNlabel() @pyqtSlot() def onToggleConsole(self): if self.btn_consoleToggle.text() == 'Hide': self.btn_consoleToggle.setText('Show') self.consoleArea.hide() self.console.setMinimumHeight(70) self.console.setMaximumHeight(70) else: self.console.setMinimumHeight(70) self.console.setMaximumHeight(starting_height) self.btn_consoleToggle.setText('Hide') self.consoleArea.show() def showHWstatus(self): self.updateHWleds() self.myPopUp2(QMessageBox.Information, 'QMT - hw check', "%s" % self.hwStatusMess, QMessageBox.Ok) def showRPCstatus(self): self.updateRPCled() self.myPopUp2(QMessageBox.Information, 'QMT - rpc check', "%s" % self.rpcStatusMess, QMessageBox.Ok) def updateHWleds(self): if self.hwStatus == 1: self.header.hwLed.setPixmap(self.ledHalfPurpleH_icon) elif self.hwStatus == 2: self.header.hwLed.setPixmap(self.ledPurpleH_icon) else: self.header.hwLed.setPixmap(self.ledGrayH_icon) self.header.hwLed.setToolTip(self.hwStatusMess) def updateHWstatus(self, ctrl): if self.hwdevice is not None: if hasattr(self.hwdevice, 'dongle'): self.hwdevice.dongle.close() self.hwdevice = HWdevice() statusCode, statusMess = self.hwdevice.getStatus() printDbg("mess: %s" % statusMess) if statusCode != 2: # If is not connected try again try: if hasattr(self.hwdevice, 'dongle'): self.hwdevice.dongle.close() self.hwdevice = HWdevice() self.hwdevice.initDevice() statusCode, statusMess = self.hwdevice.getStatus() except Exception as e: err_msg = "error in checkHw" printException(getCallerName(), getFunctionName(), err_msg, e.args) self.hwStatus = statusCode self.hwStatusMess = statusMess # if all is good connect the signals if statusCode == 2: self.hwdevice.sigTxdone.connect(self.t_rewards.FinishSend) self.hwdevice.sigTxabort.connect(self.t_rewards.onCancel) self.hwdevice.tx_progress.connect(self.t_rewards.updateProgressPercent) def updateLastBlockLabel(self): text = '--' if self.rpcLastBlock == 1: text = "Loading block index..." elif self.rpcLastBlock > 0 and self.rpcConnected: text = str(self.rpcLastBlock) text += " (" if not self.isBlockchainSynced: text += "Synchronizing" else: text += "Synced" text += ")" self.header.lastBlockLabel.setText(text) def updateRPCled(self): if self.rpcConnected: self.header.rpcLed.setPixmap(self.ledPurpleH_icon) else: if self.rpcLastBlock == 1: self.header.rpcLed.setPixmap(self.ledHalfPurpleH_icon) else: self.header.rpcLed.setPixmap(self.ledGrayH_icon) self.header.rpcLed.setToolTip(self.rpcStatusMess) self.updateLastBlockLabel() def updateRPCstatus(self, ctrl): if self.rpcClient is None: self.rpcClient = RpcClient() status, statusMess, lastBlock = self.rpcClient.getStatus() self.rpcConnected = status self.rpcLastBlock = lastBlock self.rpcStatusMess = statusMess self.isBlockchainSynced = self.rpcClient.isBlockchainSynced() # If is not connected try again if not status: self.rpcClient = RpcClient()
class mainWindow(QMainWindow): disableProjectMenu = pyqtSignal() enableProjectMenu = pyqtSignal() def __init__(self, parent=None): super(mainWindow, self).__init__(parent) self.ui = loadUi('UI/mainFrame.ui', self) self.mainWidget = QWidget(self) self.mainWidgetLayout = QVBoxLayout(self.mainWidget) self.setCentralWidget(self.mainWidget) self.setWindowIcon(QIcon('res/pluto.ico')) ############################### # local variables self.defaultDir = '.' self.curOpenProjectHandle = None self.curProjectTabManager = None self.openedProject = ProjectQueue() self.handleToTabWidget = dict() self.plutoVariables = plutoVariables() # flags ############################### # menu newProjectMenu = self.ui.actionNew_Project newProjectMenu.triggered.connect(self.newProjectDialog) openProjectMenu = self.ui.actionOpen_Project openProjectMenu.triggered.connect(self.openProjectDialog) saveProjectMenu = self.ui.actionSave_Project saveProjectMenu.triggered.connect(self.saveProject) self.newProjectDataSetMenu = self.ui.actionNew_DataSet self.newProjectDataSetMenu.triggered.connect( self.onNewProjectDataSetMenu) self.newProjectModel = self.ui.actionNew_Model self.newProjectModel.triggered.connect(self.onNewProjectModel) self.newProjectScript = self.ui.actionNew_Script self.newProjectScript.triggered.connect(self.onNewProjectScript) self.newProjectDataSetMenu.setEnabled(False) self.newProjectModel.setEnabled(False) self.newProjectScript.setEnabled(False) ############################### # init toolbar status bar self.toolBar = QToolBar(self) self.statusBar = QStatusBar(self) self.openAction = QAction(QIcon('res/Open.ico'), 'Open Project', self) self.homePageAction = QAction(QIcon('res/homepage.png'), 'HOME', self) self.projectAction = QAction(QIcon('res/ProjectManager.ico'), 'Project Manager', self) ############################### # init widgets self.leftStage = QTabWidget(self) self.mainStage = QWidget(self) self.bottomStage = QWidget(self) self.bottomLayout = QHBoxLayout(self.bottomStage) self.bottomTabWidget = CollapsibleTabWidget(0, self) self.mainLayout = QStackedLayout(self.mainStage) ############################### # splitter self.vertical_splitter = QSplitter(Qt.Horizontal) self.horizontal_splitter = QSplitter(Qt.Vertical) self.downSize = 0.22 * self.height() ############################### # left stage self.leftTreeView = QTreeView(self) ############################### # bottom stage self.bottomOutputView = QTextEdit(self) ############################### # main stage self.scrollarea = QScrollArea(self) self.scrollbar = QScrollBar(self) self.projectList = QWidget(self.scrollarea) self.projectListLayout = FlowLayout() self.initUI() self.initToolBar() self.setContextMenuPolicy( Qt.NoContextMenu) # close right click of mainWindow def initUI(self): self.mainStage.setLayout(self.mainLayout) # setup splitter self.vertical_splitter.addWidget(self.leftStage) self.vertical_splitter.addWidget(self.mainStage) self.vertical_splitter.setStretchFactor(1, 1) self.vertical_splitter.setCollapsible(0, False) self.vertical_splitter.setCollapsible(1, False) self.horizontal_splitter.addWidget(self.vertical_splitter) self.horizontal_splitter.addWidget(self.bottomStage) self.horizontal_splitter.setStretchFactor(1, 1) self.horizontal_splitter.setCollapsible(0, False) self.horizontal_splitter.setCollapsible(1, False) self.vertical_splitter.setSizes( [self.width() * 0.22, self.width() * 0.78]) # self.horizontal_splitter.setSizes([self.height() * 0.78, self.height() * 0.22]) self.horizontal_splitter.setSizes( [self.height() - self.downSize, self.downSize]) self.horizontal_splitter.splitterMoved.connect(self.onHSplitterMoved) self.mainWidgetLayout.addWidget(self.horizontal_splitter) self.bottomStage.setLayout(self.bottomLayout) self.bottomTabWidget.setSplitter(self.horizontal_splitter) self.bottomLayout.addWidget(self.bottomTabWidget) # setup left stage self.leftStage.setTabPosition(QTabWidget.West) self.leftStage.addTab(self.leftTreeView, 'File') # setup bottom stage # self.bottomStage.setTabPosition(QTabWidget.South) self.bottomTabWidget.addTab(self.bottomOutputView, 'Output') self.bottomLayout.setContentsMargins(20, 0, 0, 0) # init main stage self.initProjectList() # connect self.disableProjectMenu.connect(self.onDisableProjectMenu) self.enableProjectMenu.connect(self.onEnableProjectMenu) def initToolBar(self): self.statusBar.setContentsMargins(10, 0, 0, 10) self.addToolBar(self.toolBar) self.setStatusBar(self.statusBar) # open self.openAction.setStatusTip('Open Project') self.openAction.triggered.connect(self.openProjectDialog) self.toolBar.addAction(self.openAction) self.homePageAction.setStatusTip('Home Page') self.homePageAction.triggered.connect(self.jumpToHomePage) self.toolBar.addAction(self.homePageAction) self.projectAction.setStatusTip('Project Manager') self.projectAction.triggered.connect(self.showOpenProject) self.toolBar.addAction(self.projectAction) def initProjectList(self): self.scrollarea.setWidgetResizable(True) self.projectList.setLayout(self.projectListLayout) self.scrollarea.setWidget(self.projectList) self.scrollarea.setVerticalScrollBar(self.scrollbar) self.scrollarea.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn) self.mainLayout.addWidget(self.scrollarea) # init projects from plutoVariables projectFiles projectHandleList = [] # projectItemList = [] for projectPath in self.plutoVariables.projectFiles: projectHandle = ProjectReader(projectPath) projectHandleList.append(projectHandle) # projectName, projectLocation, lastOpenTime, projectFiles projectItem = ProjectWidget(projectHandle.projectName, projectHandle.projectPath, projectHandle.lastAccessTime, projectHandle) projectItem.triggered.connect(self.openProject) self.projectListLayout.addWidget(projectItem) def newProjectDialog(self): dialog = newProjectDialog(self) dialog.projectInited.connect(self.onProjectInited) dialog.show() def openProject(self, handle: ProjectReader): if self.openedProject.isExist(handle): QMessageBox.information( self, 'open project', "project \"" + handle.projectName + "\" has been opened") else: print('open project:', handle.projectName) tabWidget = ColorTabWidget(self) tabManager = self.initTabWidget(tabWidget, handle) self.openedProject.add(handle, tabManager) self.mainLayout.addWidget(tabWidget) self.mainLayout.setCurrentIndex(self.openedProject.currentIndex) self.curOpenProjectHandle = handle # self.openedProject.getHandle(self.openedProject.currentIndex) self.curProjectTabManager = tabManager self.updateProjectLastAccessTime() self.enableProjectMenu.emit() def closeProject(self): if self.curOpenProjectHandle: self.saveProject() self.curOpenProjectHandle = None gc.collect() def saveProject(self): # TODO print('save project') if not self.curOpenProjectHandle: QMessageBox.information(self, 'Save Project', 'No open project', QMessageBox.Ok) else: self.curOpenProjectHandle.saveToYaml() QMessageBox.information( self, 'Save Project', 'Project Saved to ' + self.curOpenProjectHandle.yamlFile, QMessageBox.Ok) def changeProjectName(self, name): self.curOpenProjectHandle.setProjectName(name) self.curOpenProjectHandle.updateToYamlDict() def updateProjectLastAccessTime(self): currentTime = datetime.utcnow() self.curOpenProjectHandle.setLastAccessTime(currentTime) self.curOpenProjectHandle.updateToYamlDict() def addFileToProject(self): # TODO pass def delFileFromProject(self): # TODO pass def openProjectDialog(self): dialog = QFileDialog(self) options = QFileDialog.Options() options |= QFileDialog.DontUseNativeDialog dialog.setDirectory(self.defaultDir) projectFile, _ = dialog.getOpenFileName( self, "Open Project", "", "Project File (*.pluto);;All Files (*.*)", options=options) if projectFile: handle = ProjectReader(projectFile) self.openProject(handle) else: raise Exception('Open project failed') def jumpToHomePage(self): self.mainLayout.setCurrentIndex(0) self.disableProjectMenu.emit() def showOpenProject(self): # display a pop menu of current open project if not len(self.openedProject): print('no opened project') return allOpenedProjectID = self.openedProject.getAllID() openedProjectMenu = QMenu() for index, ID in enumerate(allOpenedProjectID): if not ID: continue handle = self.openedProject.getHandle(index) oneProject = QAction(handle.projectName, self) oneProject.triggered.connect(partial(self.showProjectPage, index)) openedProjectMenu.addAction(oneProject) self.projectAction.setMenu(openedProjectMenu) openedProjectMenu.exec(QCursor.pos()) def showProjectPage(self, index): # show opened project page using index self.mainLayout.setCurrentIndex(index) self.curOpenProjectHandle, self.curProjectTabManager = self.openedProject.getHandle( index) self.enableProjectMenu.emit() def initTabWidget(self, tabWidget: ColorTabWidget, handle: ProjectReader): tabManager = TabManager(tabWidget, handle) # init qml main page list projectMainPage = QQuickWidget(tabWidget) projectMainPage.setResizeMode(QQuickWidget.SizeRootObjectToView) projectMainPage.setSource( QUrl.fromLocalFile('QML/ProjectMainPage.qml')) projectMainPage.setMinimumWidth(550) projectMainPage.setMinimumHeight(250) projectMainPage.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) obj_projectMainPage = projectMainPage.rootObject() # send main page init dict obj_projectMainPage.onInitMainPageItems( self.getProjectDetail(tabManager)) obj_projectMainPage.sendData.connect(self.getData_ProjectMainPage) tabManager.qmlHandle = obj_projectMainPage tabManager.qmlWidget = projectMainPage tabWidget.addTab(projectMainPage, 'MainPage:MainPage') return tabManager @staticmethod def getProjectDetail(tabManager: TabManager): info = dict() handle = tabManager.handle info['ID'] = handle.yamlFile info['projectName'] = handle.projectName info['lastAccessTime'] = handle.lastAccessTime.replace( tzinfo=timezone.utc).astimezone( tz=None).strftime('%y/%m/%d %H:%M:%S') info['model'] = handle.modelSourceHandle.getAllPath() info['data'] = handle.dataSourceHandle.getAllPath() info['script'] = handle.scriptSourceHandle.getAllPath() info['result'] = [] return info def onProjectInited(self, projectFile: str): handle = ProjectReader(projectFile) self.openProject(handle) def getData_ProjectMainPage(self, data): dataType, itemIndex, itemName = data.toVariant() # print(dataType, itemIndex, itemName) if dataType == 'data': handle = dataLoader(itemName) self.openDSEditor(handle) def changeEvent(self, e: QEvent) -> None: if e.type() == QEvent.WindowStateChange and self.windowState( ) == Qt.WindowMaximized: self.horizontal_splitter.setSizes( [self.height() - self.downSize, self.downSize]) elif e.type() == QEvent.WindowStateChange and self.windowState( ) == Qt.WindowNoState: self.horizontal_splitter.setSizes( [self.height() - self.downSize, self.downSize]) def onHSplitterMoved(self, pos: int, index: int): self.downSize = self.height() - pos def onDisableProjectMenu(self): self.newProjectDataSetMenu.setEnabled(False) self.newProjectModel.setEnabled(False) self.newProjectScript.setEnabled(False) def onEnableProjectMenu(self): self.newProjectDataSetMenu.setEnabled(True) self.newProjectModel.setEnabled(True) self.newProjectScript.setEnabled(True) def onNewProjectDataSetMenu(self): dialog = newPlutoDSDialog(self.curOpenProjectHandle, self) r = dialog.exec() if r == QDialog.Accepted: obj_projectMainPage = self.curProjectTabManager.qmlWidget.rootObject( ) obj_projectMainPage.addData(dialog.target) handle = dataLoader(dialog.target) self.openDSEditor(handle) def onNewProjectModel(self): pass def onNewProjectScript(self): pass def openDSEditor(self, DSHandle): tabManager = self.curProjectTabManager tabWidget = tabManager.tabWidget if DSHandle.yamlFile in tabManager.dataTabs: print(tabManager.dataTabs[DSHandle.yamlFile]) tabWidget.setCurrentIndex( tabManager.dataTabs[DSHandle.yamlFile][0]) else: widget, title = self.DSEditor(DSHandle, tabWidget) tabWidget.addTab(widget, title) tabManager.dataTabs[ DSHandle.yamlFile] = tabWidget.count() - 1, widget tabWidget.setCurrentIndex(tabWidget.count() - 1) def DSEditor(self, DSHandle: dataLoader, parent=None): handle = DSHandle widget = QWidget(parent) title = 'Data:' + QDir(handle.yamlFile).dirName() return widget, title