class SummarySection(QTabWidget): """ Represents the summary section. Takes reply data from main ui and updates it's tabs Keeps track of cumulative summary data. """ def __init__(self, parent=None): super(SummarySection, self).__init__(parent) self.text_edit_summary = QTextEdit() self.text_edit_summary.setReadOnly(True) self.addTab(self.text_edit_summary, "Output") self.ball_grid = BallGrid(30, 30, 2) self.addTab(self.ball_grid, "Led View") self.tab_summary = SummaryTab() self.addTab(self.tab_summary, "Summary") #some private fields, keep track of accumulated summary data self.current_ip = 0 #we take reply data for ips in order self.sent_packets = 0 self.received_packets = 0 self.average_delay = 0 def setIPs(self, ips): #this indicates the start of a new ping, could be treated #as a pingStarted signal self.current_ip = 0 self.sent_packets = 0 self.received_packets = 0 self.average_delay = 0 self.text_edit_summary.clear() self.ball_grid.layoutForIps(ips) self.tab_summary.zeroOut() def takeReplyData(self, replyData, sentPackets): #sent packets is passed in as extra """ Update the output text area with the replyData string representation Set proper widget states on the BallGrid Calculate summaries cumulatively and set them for display on the summary tab """ self.text_edit_summary.append(str(replyData)) packets_lost = replyData.packets_lost if packets_lost: self.ball_grid.setStateAt(self.current_ip, BallWidget.UNREACHABLE) else: self.ball_grid.setStateAt(self.current_ip, BallWidget.REACHABLE) self.current_ip += 1 self.sent_packets += sentPackets self.received_packets = self.sent_packets - replyData.packets_lost self.average_delay += (replyData.rtt / self.current_ip) #the current_ip reflects the overall number of replies summary_data = SummaryData(self.sent_packets, self.received_packets, self.average_delay) self.tab_summary.setSummaryData(summary_data) def pingingStoppedHandler(self): self.ball_grid.pingingCancelledHandler()
class Console(): def __init__(self, targetLayoutContainer): self.textarea = QTextEdit() self.commits = QListWidget() self.commits.addAction(QAction('Rollback to this revision', self.commits, triggered=self.rollback)) self.commits.setContextMenuPolicy(Qt.ActionsContextMenu) self.widget = QTabWidget() self.widget.addTab(self.textarea, 'Log') self.widget.addTab(self.commits, 'Commits') targetLayoutContainer.addWidget(self.widget) def color(self, module, function, color, *args): print module, function, args prettyString = '<font color="' + color + '"><b>', module, '</b><i>::', function, '</i> --> ', ''.join(args), '</font>' self.textarea.append(''.join(prettyString)) def info(self, module, function, *args): print module, function, args prettyString = '<font color="black"><b>', module, '</b><i>::', function, '</i> --> ', ''.join(args), '</font>' self.textarea.append(''.join(prettyString)) def error(self, module, function, *args): print module, function, args prettyString = '<font color="red"><b>', module, '</b><i>::', function, '</i> --> ', ''.join(args), '</font>' self.textarea.append(''.join(prettyString)) def warn(self, module, function, *args): print module, function, args prettyString = '<font color="#BE9900"><b>', module, '</b><i>::', function, '</i> --> ', ''.join(args), '</font>' self.textarea.append(''.join(prettyString)) def set_commits(self, commits): self.commits.clear() for commit in commits: self.commits.addItem(commit) def clear(self): self.textarea.clear() def rollback(self): targetCommit = self.commits.currentItem().text().split(' ')[0] if QMessageBox.warning(None, 'Rollback to commit?', 'All commits after ' + targetCommit + ' will be lost, proceed?', QMessageBox.Yes, QMessageBox.No) == QMessageBox.Yes: rollback(targetCommit)
class LoggingArea(QWidget): def __init__(self, parent=None): super(LoggingArea, self).__init__() self.layout = QVBoxLayout(self) self.hbox_buttons_top = QHBoxLayout(self) self.button_start = QPushButton('Start Logging', self) self.button_start.clicked.connect(parent._start_logging) self.hbox_buttons_top.addWidget(self.button_start) self.button_stop = QPushButton('Stop Logging', self) self.button_stop.clicked.connect(parent._stop_logging) self.hbox_buttons_top.addWidget(self.button_stop) self.layout.addLayout(self.hbox_buttons_top) self.te_logging = QTextEdit(self) self.layout.addWidget(self.te_logging) self.hbox_buttons_bottom = QHBoxLayout(self) self.button_clear = QPushButton('Clear Data', self) self.button_clear.clicked.connect(self._clear_data) self.hbox_buttons_bottom.addWidget(self.button_clear) self.button_clipboard = QPushButton('Copy to Clipboard', self) self.button_clipboard.clicked.connect(self._copy_to_cliboard) self.hbox_buttons_bottom.addWidget(self.button_clipboard) # self.button_file = QPushButton('Save to CSV', self) # self.button_file.clicked.connect(self._save_to_csv) # # self.button_file.setEnabled(False) # self.hbox_buttons_bottom.addWidget(self.button_file) self.layout.addLayout(self.hbox_buttons_bottom) self.setLayout(self.layout) def _clear_data(self): self.te_logging.clear() def _copy_to_cliboard(self): self.te_logging.selectAll() self.te_logging.copy() def _save_to_csv(self): results = self.te_logging.toPlainText() print results
class Prozor(QWidget): def __init__(self,element): #kreiramo prozor QWidget.__init__(self) self.element = element #iskljucujemo polja za uvecanje i minimizaciju self.setWindowFlags(self.windowFlags() & ~Qt.WindowMaximizeButtonHint & ~Qt.WindowMinimizeButtonHint) #Podesavamo naslov self.setWindowTitle(self.element.ime) self.focusWidget() #editor teksta self.textEditor = QTextEdit() self.textEditor.setText(self.element.data) #dodajemo dugmad za primenu i odbacivanje promena #i povezujemo ih sa odgovarajucim funkcijama self.dugmeOk = QPushButton("Potvrdi") self.dugmeOtkazi = QPushButton("Otkazi") self.connect(self.dugmeOk,SIGNAL('clicked()'),self,SLOT('podesi()')) self.connect(self.dugmeOtkazi,SIGNAL('clicked()'),self,SLOT('zatvori()')) #formiramo raspored raspored = QFormLayout() raspored.addRow(self.textEditor) raspored.addRow(self.dugmeOtkazi,self.dugmeOk) self.setLayout(raspored) def zatvori(self): ''' Funkcija za dugme otkazi promene, vraca parametre liste na trenutno stanje aplikacije ''' self.textEditor.clear() self.textEditor.setText(self.element.data) self.hide() def podesi(self): ''' Funkcija za dugme potvrdi promene, poziva akcije za izmenu jezika i izgleda ''' self.element.data = self.textEditor.toPlainText() self.hide() def closeEvent(self, event): self.zatvori()
class CardBordAIApp(QWidget): def __init__(self, parent=None): super().__init__(parent) self.setWindowTitle("CardBord AI Demo ver0.10") self.operator = Operator() self.setupUi() self.operator.speach.connect(self.speak_ai) self.init() def setupUi(self): self.mainlayout = QVBoxLayout(self) self.title = QLabel("CardBord Operator", self) self.mainlayout.addWidget(self.title) self.user_txtarea = QTextEdit(self) self.ai_txtarea = QTextEdit(self) self.users_edit_title = QLabel("質問に答えてください") self.users_edit = QLineEdit("", self) self.txtarea_layout = QHBoxLayout() self.txtarea_layout.addWidget(self.user_txtarea) self.txtarea_layout.addWidget(self.ai_txtarea) self.mainlayout.addLayout(self.txtarea_layout) self.mainlayout.addWidget(self.users_edit_title) self.mainlayout.addWidget(self.users_edit) self.send_btn = QPushButton("send", self) self.send_btn.setObjectName("send_btn") self.mainlayout.addWidget(self.send_btn) QMetaObject.connectSlotsByName(self) def init(self): # Talkエリアの初期化 self.user_txtarea.clear() self.ai_txtarea.clear() # オペレータ初期化、初期ワード取得 self.operator.init() @Slot() def on_send_btn_clicked(self): # UI処理 user_word = self.users_edit.text() if user_word == "": return None self.users_edit.clear() self.user_txtarea.append(user_word) # サーバー(エンジン)へユーザワードを送信 self.operator.send(user_word) @Slot() def speak_ai(self, word): # AIのトークを表示 # ディレイを使ってテンポを整える def wrapper(): self.ai_txtarea.append(word) QTimer.singleShot(TALK_DELAY, wrapper)
class MainWindow(QMainWindow): def __init__(self): # QMainWindow.__init__(self) super().__init__() # use super() to avoid explicit dependency on the base class name # Note: must not pass the self reference to __init__ in this case! self.resize(800, 600) # Create the main content widget mainWidget = QWidget(self) self.setCentralWidget(mainWidget) # Create a text component at the top area of the main widget self.output = QTextEdit(mainWidget) self.output.setReadOnly(True) self.output.setLineWrapMode(QTextEdit.NoWrap); # set the font font = self.output.font() font.setFamily("Courier") font.setPointSize(10) self.output.setFont(font) # Set the background color # self.output.setTextBackgroundColor(Qt.red) # Only sets the background color for the text itself, not for the whole widget pal = self.output.palette() pal.setColor(QPalette.Base, Qt.black) self.output.setPalette(pal) mainLayout = QVBoxLayout(mainWidget) mainLayout.addWidget(self.output) # Create buttons in a grid layout below the top area buttonWidget = QWidget(mainWidget) self.buttonLayout = QGridLayout(buttonWidget) mainLayout.addWidget(buttonWidget) # Add some buttons to execute python code self.row = 0 self.column = 0 self.addButton("Clear console", lambda : self.output.clear()) self.newRow() # Add buttons for all the examples - attention: do not make "examples" # a local variable - otherwise, the Examples object would be destroyed # at the end of __init__ !!! self.examples = samplePackage.SampleModule.Examples(self) for example in self.examples.getExamples(): if example is None: self.newRow() else: self.addButton(example.label, example.function) # In a Python program, sys.excepthook is called just before the program exits. # So we can catch all fatal, uncaught exceptions and log them. # NOTE: we must be sure not to set the excepthook BEFORE we an actually # log something!! sys.excepthook = self.logException self.writelnColor(Qt.magenta, "Python version: {0}.{1}.{2} ({3})".format( sys.version_info[0], sys.version_info[1], sys.version_info[2], sys.version_info[3])) self.writelnColor(Qt.magenta, "Qt version : {0}".format(qVersion())) def logException(self, exctype, value, tb): self.writelnColor(Qt.red, ("\nFATAL ERROR: Uncaught exception\n" " {}: {}\n" "{}\n".format(exctype.__name__, value, ''.join(traceback.format_tb(tb)))) ) def addButton(self, label, function): theButton = QPushButton(label) theButton.clicked.connect(function) self.buttonLayout.addWidget(theButton, self.row, self.column) self.column += 1 def newRow(self): self.row += 1 self.column = 0 def writeColor(self, color, *text): theText = ' '.join(map(str, text)) self.output.setTextColor(color) # Note: append() adds a new paragraph! #self.output.append(theText) self.output.textCursor().movePosition(QTextCursor.End) self.output.insertPlainText(theText) # scroll console window to bottom sb = self.output.verticalScrollBar() sb.setValue(sb.maximum()) def write(self, *text): self.writeColor(Qt.green, *text) def writelnColor(self, color, *text): self.writeColor(color, *text) self.write('\n') def writeln(self, *text): self.writelnColor(Qt.green, *text)
class MainWindow(QMainWindow): windows = [] def __init__(self): super(MainWindow, self).__init__() # Store ourself. self.windows.append(self) # State! self.current_file = None # Editor! self.editor = QTextEdit() self.setCentralWidget(self.editor) # Style the editor #style.apply_stylesheet(self.editor, 'editor.qss') # Menus and Stuff! self.init_actions() self.init_menus() self.init_toolbars() self.init_statusbar() # Settings! self.init_settings() # Icons! self.reload_icons() #style.style_reloaded.connect(self.reload_icons) # Fancy! #style.enable_aero(self) self.update_title() # Now, for some plugins. # plugins.run_signal('new_window', self) ##### Action Icons! ####################################################### def reload_icons(self): #self.setWindowIcon(style.icon('application')) pass # a = self.actions # for key in a.keys(): # a[key].setIcon(style.icon(key.lower())) ##### Actions! ############################################################ def init_actions(self): self.actions = a = {} ##### File Menu ####################################################### a['document-new'] = QAction("&New", self, shortcut=QKeySequence.New, statusTip="Create a new file.", triggered=self.action_new) a['document-open'] = QAction("&Open", self, shortcut=QKeySequence.Open, statusTip="Open an existing file.", triggered=self.action_open) a['document-save'] = QAction("&Save", self, shortcut=QKeySequence.Save, statusTip="Save the document to disk.", triggered=self.action_save) a['application-exit'] = QAction("E&xit", self, statusTip="Exit the application.", triggered=self.close) ##### Edit Menu ####################################################### a['edit-cut'] = QAction("Cu&t", self, shortcut=QKeySequence.Cut, triggered=self.editor.cut) a['edit-copy'] = QAction("&Copy", self, shortcut=QKeySequence.Copy, triggered=self.editor.copy) a['edit-paste'] = QAction("&Paste", self, shortcut=QKeySequence.Paste, triggered=self.editor.paste) a['edit-cut'].setEnabled(False) a['edit-copy'].setEnabled(False) self.editor.copyAvailable.connect(a['edit-cut'].setEnabled) self.editor.copyAvailable.connect(a['edit-copy'].setEnabled) ##### Tool Menu ####################################################### # This is the fun part. a['addon-manager'] = QAction("&Add-ons", self, shortcut="Ctrl+Shift+A", statusTip="Display the Add-ons manager.", triggered=addons.show) # a['view-refresh'] = QAction("&Reload Style", self, # shortcut="Ctrl+Shift+R", # statusTip="Reload the style.", # triggered=style.reload) ##### Menus! ############################################################## def init_menus(self): self.menuBar().clear() a = self.actions file = self.menuBar().addMenu("&File") file.addAction(a['document-new']) file.addAction(a['document-open']) file.addAction(a['document-save']) file.addSeparator() file.addAction(a['application-exit']) edit = self.menuBar().addMenu("&Edit") edit.addAction(a['edit-cut']) edit.addAction(a['edit-copy']) edit.addAction(a['edit-paste']) tools = self.menuBar().addMenu("&Tools") tools.addAction(a['addon-manager']) #tools.addAction(a['view-refresh']) ##### Explosions! ######################################################### ##### Toolbars! ########################################################### def init_toolbars(self): a = self.actions file = self.addToolBar("File") file.setObjectName('filebar') file.addAction(a['document-new']) file.addAction(a['document-open']) file.addAction(a['document-save']) edit = self.addToolBar("Edit") edit.setObjectName('editbar') edit.addAction(a['edit-cut']) edit.addAction(a['edit-copy']) edit.addAction(a['edit-paste']) tools = self.addToolBar("Tools") tools.setObjectName('toolsbar') tools.addAction(a['addon-manager']) #tools.addAction(a['view-refresh']) ##### Statusbars! ######################################################### def init_statusbar(self): self.statusBar().showMessage("Ready.") ##### Settings! ########################################################### def init_settings(self): self.restoreGeometry(profile.get("geometry")) self.restoreState(profile.get("state")) def save_settings(self): profile.set("geometry", self.saveGeometry()) profile.set("state", self.saveState()) ##### Actual Actions! ##################################################### def update_title(self): if self.current_file: title = os.path.basename(self.current_file) else: title = "Untitled" self.setWindowTitle("%s - %s" % (title, QApplication.instance().applicationName())) def action_new(self): if self.try_save(): self.editor.clear() self.current_file = None self.update_title() def action_open(self): if self.try_save(): fn = QFileDialog.getOpenFileName(self)[0] if not fn: return self.do_open(fn) def do_open(self, fn): with open(fn, 'r') as f: content = f.read() self.editor.setPlainText(content) self.current_file = fn self.update_title() def action_save(self): if not self.editor.document().isModified(): return if not self.current_file: self.current_file = QFileDialog.getSaveFileName(self)[0] self.update_title() if not self.current_file: return with open(self.current_file, 'w') as f: f.write(self.editor.toPlainText()) self.editor.document().setModified(False) ##### Adventure! ########################################################## def try_save(self): if self.editor.document().isModified(): ret = QMessageBox.warning( self, "Blah Blah Blah", "That's an awfully nice modified document you've got there" ". It'd be a shame if anything... happened to it. Catch " "my drift?", QMessageBox.Save | QMessageBox.Discard | QMessageBox.Cancel) if ret == QMessageBox.Save: self.action_save() elif ret == QMessageBox.Cancel: return False return True def showRaise(self): """ Show and raise the window. """ # self.show() # self.raise_() # self.setFocus() self.activateWindow() if self.isMinimized(): self.showNormal() def closeEvent(self, event): if self.try_save(): self.save_settings() if self in self.windows: self.windows.remove(self) # plugins.run_signal('close_window', self) event.accept() else: event.ignore()
class TransferPanel(QWidget): ''' Transfer Panel This Panel is the main dialog box for the Dive Computer Transfer GUI ''' def __init__(self, parent=None): super(TransferPanel, self).__init__(parent) self._logbook = None self._logbookName = 'None' self._logbookPath = None self._createLayout() self._readSettings() self.setWindowTitle(self.tr('DC Transfer - %s') % self._logbookName) def _createLayout(self): 'Create the Widget Layout' self._txtLogbook = QLineEdit() self._txtLogbook.setReadOnly(True) self._lblLogbook = QLabel(self.tr('&Logbook File:')) self._lblLogbook.setBuddy(self._txtLogbook) self._btnBrowse = QPushButton('...') self._btnBrowse.clicked.connect(self._btnBrowseClicked) self._btnBrowse.setStyleSheet('QPushButton { min-width: 24px; max-width: 24px; }') self._btnBrowse.setToolTip(self.tr('Browse for a Logbook')) self._cbxComputer = QComboBox() self._lblComputer = QLabel(self.tr('Dive &Computer:')) self._lblComputer.setBuddy(self._cbxComputer) self._btnAddComputer = QPushButton(QPixmap(':/icons/list-add.png'), self.tr('')) self._btnAddComputer.setStyleSheet('QPushButton { min-width: 24px; min-height: 24; max-width: 24px; max-height: 24; }') self._btnAddComputer.clicked.connect(self._btnAddComputerClicked) self._btnRemoveComputer = QPushButton(QPixmap(':/icons/list-remove.png'), self.tr('')) self._btnRemoveComputer.setStyleSheet('QPushButton { min-width: 24px; min-height: 24; max-width: 24px; max-height: 24; }') self._btnRemoveComputer.clicked.connect(self._btnRemoveComputerClicked) hbox = QHBoxLayout() hbox.addWidget(self._btnAddComputer) hbox.addWidget(self._btnRemoveComputer) gbox = QGridLayout() gbox.addWidget(self._lblLogbook, 0, 0) gbox.addWidget(self._txtLogbook, 0, 1) gbox.addWidget(self._btnBrowse, 0, 2) gbox.addWidget(self._lblComputer, 1, 0) gbox.addWidget(self._cbxComputer, 1, 1) gbox.addLayout(hbox, 1, 2) gbox.setColumnStretch(1, 1) self._pbTransfer = QProgressBar() self._pbTransfer.reset() self._txtStatus = QTextEdit() self._txtStatus.setReadOnly(True) self._btnTransfer = QPushButton(self.tr('&Transfer Dives')) self._btnTransfer.clicked.connect(self._btnTransferClicked) self._btnExit = QPushButton(self.tr('E&xit')) self._btnExit.clicked.connect(self.close) hbox = QHBoxLayout() hbox.addWidget(self._btnTransfer) hbox.addStretch() hbox.addWidget(self._btnExit) vbox = QVBoxLayout() vbox.addLayout(gbox) vbox.addWidget(self._pbTransfer) vbox.addWidget(self._txtStatus) vbox.addLayout(hbox) self.setLayout(vbox) def _closeLogbook(self): 'Close the current Logbook' if self._logbook is None: return self._logbook = None self._logbookName = 'None' self._logbookPath = None self._txtLogbook.clear() self._cbxComputer.setModel(None) self._writeSettings() self.setWindowTitle(self.tr('DC Transfer - %s') % self._logbookName) def _openLogbook(self, path): 'Open an existing Logbook' if self._logbook is not None: self._closeLogbook() if not os.path.exists(path): QMessageBox.critical(self, self.tr('Missing Logbook'), self.tr('Logbook File "%s" does not exist.') % path) return #TODO: Handle a Schema Upgrade in a user-friendly manner self._logbook = Logbook(path, auto_update=False) self._logbookName = os.path.basename(path) self._logbookPath = path self._txtLogbook.setText(self._logbookPath) self._cbxComputer.setModel(DiveComputersModel(self._logbook)) self._writeSettings() self.setWindowTitle(self.tr('DC Transfer - %s') % self._logbookName) def _readSettings(self): 'Read main window settings from the configuration' settings = QSettings() settings.beginGroup('MainWindow') max = settings.value('max') size = settings.value('size') pos = settings.value('pos') file = settings.value('file') settings.endGroup() # Size and Position the Main Window if size is not None: self.resize(size) if pos is not None: self.move(pos) # HAX because QVariant is not exposed in PySide and the default # coercion to string is just stupid if max is not None and (max == 'true'): self.showMaximized() # Open the Logbook if file is not None: self._openLogbook(file) def _writeSettings(self): 'Write settings to the configuration' settings = QSettings() settings.beginGroup('MainWindow') settings.setValue('pos', self.pos()) settings.setValue('size', self.size()) settings.setValue('max', self.isMaximized()) settings.setValue('file', self._logbookPath) settings.endGroup() def closeEvent(self, e): 'Intercept an OnClose event' self._writeSettings() e.accept() #-------------------------------------------------------------------------- # Slots @QtCore.Slot() def _btnAddComputerClicked(self): 'Add a Dive Computer' dc = AddDiveComputerWizard.RunWizard(self) if dc is not None: self._logbook.session.add(dc) self._logbook.session.commit() self._cbxComputer.model().reload() self._cbxComputer.setCurrentIndex(self._cbxComputer.findText(dc.name)) @QtCore.Slot() def _btnRemoveComputerClicked(self): 'Remove a Dive Computer' idx = self._cbxComputer.currentIndex() dc = self._cbxComputer.itemData(idx, Qt.UserRole+0) if QMessageBox.question(self, self.tr('Delete Dive Computer?'), self.tr('Are you sure you want to delete "%s"?') % dc.name, QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes) == QMessageBox.Yes: self._logbook.session.delete(dc) self._logbook.session.commit() self._cbxComputer.model().reload() @QtCore.Slot() def _btnBrowseClicked(self): 'Browse for a Logbook File' if self._logbook is not None: dir = os.path.dirname(self._logbookPath) else: dir = os.path.expanduser('~') fn = QFileDialog.getOpenFileName(self, caption=self.tr('Select a Logbook file'), dir=dir, filter='Logbook Files (*.lbk);;All Files(*.*)')[0] if fn == '': return if not os.path.exists(fn): if QMessageBox.question(self, self.tr('Create new Logbook?'), self.tr('Logbook "%s" does not exist. Would you like to create it?') % os.path.basename(fn), QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes) != QMessageBox.Yes: return Logbook.Create(fn) self._openLogbook(fn) @QtCore.Slot() def _btnTransferClicked(self): 'Transfer Dives' idx = self._cbxComputer.currentIndex() dc = self._cbxComputer.itemData(idx, Qt.UserRole+0) if self._logbook.session.dirty: print "Flushing dirty session" self._logbook.rollback() self._txtLogbook.setEnabled(False) self._btnBrowse.setEnabled(False) self._cbxComputer.setEnabled(False) self._btnAddComputer.setEnabled(False) self._btnRemoveComputer.setEnabled(False) self._btnTransfer.setEnabled(False) self._btnExit.setEnabled(False) self._txtStatus.clear() thread = QThread(self) #FIXME: ZOMG HAX: Garbage Collector will eat TransferWorker when moveToThread is called #NOTE: Qt.QueuedConnection is important... self.worker = None self.worker = TransferWorker(dc) thread.started.connect(self.worker.start, Qt.QueuedConnection) self.worker.moveToThread(thread) self.worker.finished.connect(self._transferFinished, Qt.QueuedConnection) self.worker.finished.connect(self.worker.deleteLater, Qt.QueuedConnection) self.worker.finished.connect(thread.deleteLater, Qt.QueuedConnection) self.worker.progress.connect(self._transferProgress, Qt.QueuedConnection) self.worker.started.connect(self._transferStart, Qt.QueuedConnection) self.worker.status.connect(self._transferStatus, Qt.QueuedConnection) thread.start() @QtCore.Slot(str) def _transferStatus(self, msg): 'Transfer Status Message' self._txtStatus.append(msg) @QtCore.Slot(int) def _transferStart(self, nBytes): 'Transfer Thread Stated' if nBytes > 0: self._pbTransfer.setMaximum(nBytes) else: self._pbTransfer.setMaximum(100) self._pbTransfer.reset() @QtCore.Slot(int) def _transferProgress(self, nTransferred): 'Transfer Thread Progress Event' self._pbTransfer.setValue(nTransferred) @QtCore.Slot(models.Dive) def _transferParsed(self, dive): 'Transfer Thread Parsed Dive' self._logbook.session.add(dive) @QtCore.Slot() def _transferFinished(self): 'Transfer Thread Finished' self._logbook.session.commit() self._txtLogbook.setEnabled(True) self._btnBrowse.setEnabled(True) self._cbxComputer.setEnabled(True) self._btnAddComputer.setEnabled(True) self._btnRemoveComputer.setEnabled(True) self._btnTransfer.setEnabled(True) self._btnExit.setEnabled(True)
class MainWindow(QMainWindow): windows = [] def __init__(self): super(MainWindow, self).__init__() # Store ourself. self.windows.append(self) # State! self.current_file = None # Editor! self.editor = QTextEdit() self.setCentralWidget(self.editor) # Style the editor style.apply_stylesheet(self.editor, 'editor.qss') # Menus and Stuff! self.init_actions() self.init_menus() self.init_toolbars() self.init_statusbar() # Settings! self.init_settings() # Icons! self.reload_icons() style.style_reloaded.connect(self.reload_icons) # Fancy! style.enable_aero(self) self.update_title() # Now, for some plugins. plugins.run_signal('new_window', self) ##### Action Icons! ####################################################### def reload_icons(self): self.setWindowIcon(style.icon('application')) a = self.actions for key in a.keys(): a[key].setIcon(style.icon(key.lower())) ##### Actions! ############################################################ def init_actions(self): self.actions = a = {} ##### File Menu ####################################################### a['document-new'] = QAction("&New", self, shortcut=QKeySequence.New, statusTip="Create a new file.", triggered=self.action_new) a['document-open'] = QAction("&Open", self, shortcut=QKeySequence.Open, statusTip="Open an existing file.", triggered=self.action_open) a['document-save'] = QAction("&Save", self, shortcut=QKeySequence.Save, statusTip="Save the document to disk.", triggered=self.action_save) a['application-exit'] = QAction("E&xit", self, statusTip="Exit the application.", triggered=self.close) ##### Edit Menu ####################################################### a['edit-cut'] = QAction("Cu&t", self, shortcut=QKeySequence.Cut, triggered=self.editor.cut) a['edit-copy'] = QAction("&Copy", self, shortcut=QKeySequence.Copy, triggered=self.editor.copy) a['edit-paste'] = QAction("&Paste", self, shortcut=QKeySequence.Paste, triggered=self.editor.paste) a['edit-cut'].setEnabled(False) a['edit-copy'].setEnabled(False) self.editor.copyAvailable.connect(a['edit-cut'].setEnabled) self.editor.copyAvailable.connect(a['edit-copy'].setEnabled) ##### Tool Menu ####################################################### # This is the fun part. a['addon-manager'] = QAction("&Add-ons", self, shortcut="Ctrl+Shift+A", statusTip="Display the Add-ons manager.", triggered=addons.show) a['view-refresh'] = QAction("&Reload Style", self, shortcut="Ctrl+Shift+R", statusTip="Reload the style.", triggered=style.reload) ##### Menus! ############################################################## def init_menus(self): self.menuBar().clear() a = self.actions file = self.menuBar().addMenu("&File") file.addAction(a['document-new']) file.addAction(a['document-open']) file.addAction(a['document-save']) file.addSeparator() file.addAction(a['application-exit']) edit = self.menuBar().addMenu("&Edit") edit.addAction(a['edit-cut']) edit.addAction(a['edit-copy']) edit.addAction(a['edit-paste']) tools = self.menuBar().addMenu("&Tools") tools.addAction(a['addon-manager']) tools.addAction(a['view-refresh']) ##### Explosions! ######################################################### ##### Toolbars! ########################################################### def init_toolbars(self): a = self.actions file = self.addToolBar("File") file.setObjectName('filebar') file.addAction(a['document-new']) file.addAction(a['document-open']) file.addAction(a['document-save']) edit = self.addToolBar("Edit") edit.setObjectName('editbar') edit.addAction(a['edit-cut']) edit.addAction(a['edit-copy']) edit.addAction(a['edit-paste']) tools = self.addToolBar("Tools") tools.setObjectName('toolsbar') tools.addAction(a['addon-manager']) tools.addAction(a['view-refresh']) ##### Statusbars! ######################################################### def init_statusbar(self): self.statusBar().showMessage("Ready.") ##### Settings! ########################################################### def init_settings(self): self.restoreGeometry(profile.get("geometry")) self.restoreState(profile.get("state")) def save_settings(self): profile.set("geometry", self.saveGeometry()) profile.set("state", self.saveState()) ##### Actual Actions! ##################################################### def update_title(self): if self.current_file: title = os.path.basename(self.current_file) else: title = "Untitled" self.setWindowTitle("%s - %s" % (title, QApplication.instance().applicationName())) def action_new(self): if self.try_save(): self.editor.clear() self.current_file = None self.update_title() def action_open(self): if self.try_save(): fn = QFileDialog.getOpenFileName(self)[0] if not fn: return self.do_open(fn) def do_open(self, fn): with open(fn, 'r') as f: content = f.read() self.editor.setPlainText(content) self.current_file = fn self.update_title() def action_save(self): if not self.editor.document().isModified(): return if not self.current_file: self.current_file = QFileDialog.getSaveFileName(self)[0] self.update_title() if not self.current_file: return with open(self.current_file, 'w') as f: f.write(self.editor.toPlainText()) self.editor.document().setModified(False) ##### Adventure! ########################################################## def try_save(self): if self.editor.document().isModified(): ret = QMessageBox.warning(self, "Blah Blah Blah", "That's an awfully nice modified document you've got there" ". It'd be a shame if anything... happened to it. Catch " "my drift?", QMessageBox.Save | QMessageBox.Discard | QMessageBox.Cancel ) if ret == QMessageBox.Save: self.action_save() elif ret == QMessageBox.Cancel: return False return True def closeEvent(self, event): if self.try_save(): self.save_settings() if self in self.windows: self.windows.remove(self) plugins.run_signal('close_window', self) event.accept() else: event.ignore()
class qNotebook(QVBoxLayout): def __init__(self): QVBoxLayout.__init__(self) self._teditor = QTextEdit() self._teditor.setMinimumWidth(500) self._teditor.setStyleSheet("font: 12pt \"Courier\";") button_layout = QHBoxLayout() self.addLayout(button_layout) self.clear_but = qmy_button(button_layout, self.clear_all, "clear") self.copy_but = qmy_button(button_layout, self._teditor.copy, "copy") qmy_button(button_layout, self._teditor.selectAll, "select all") qmy_button(button_layout, self._teditor.undo, "undo") qmy_button(button_layout, self._teditor.redo, "redo") search_button = qButtonWithArgumentsClass("search", self.search_for_text, {"search_text": ""}) button_layout.addWidget(search_button) qmy_button(button_layout, self.save_as_html, "save notebook") self.addWidget(self._teditor) self._teditor.document().setUndoRedoEnabled(True) self.image_counter = 0 self.image_dict = {} self.image_data_dict = {} def append_text(self, text): self._teditor.append(str(text)) def search_for_text(self, search_text = " "): self._teditor.find(search_text) def clear_all(self): self._teditor.clear() self.image_dict = {} self.image_counter = 0 # newdoc = QTextDocument() # self._teditor.setDocument(newdoc) def append_image(self, fig=None): #This assumes that an image is there waiting to be saved from matplotlib self.imgdata = StringIO.StringIO() if fig is None: pyplot.savefig(self.imgdata, transparent = False, format = img_format) else: fig.savefig(self.imgdata, transparent = False, format = img_format) self.abuffer = QBuffer() self.abuffer.open(QBuffer.ReadWrite) self.abuffer.write(self.imgdata.getvalue()) self.abuffer.close() self.abuffer.open(QBuffer.ReadOnly) iReader = QImageReader(self.abuffer, img_format ) the_image = iReader.read() # the_image = the_image0.scaledToWidth(figure_width) # save the image in a file imageFileName = "image" + str(self.image_counter) + "." + img_format self.image_data_dict[imageFileName] = self.imgdata self.image_counter +=1 imageFormat = QTextImageFormat() imageFormat.setName(imageFileName) imageFormat.setWidth(image_width) self.image_dict[imageFileName] = the_image #insert the image in the text document text_doc = self._teditor.document() text_doc.addResource(QTextDocument.ImageResource, QUrl(imageFileName), the_image) cursor = self._teditor.textCursor() cursor.movePosition(QTextCursor.End) cursor.insertImage(imageFormat) def add_image_data_resource(self, imgdata, imageFileName): self.abuffer = QBuffer() self.abuffer.open(QBuffer.ReadWrite) self.abuffer.write(imgdata.getvalue()) self.abuffer.close() self.abuffer.open(QBuffer.ReadOnly) iReader = QImageReader(self.abuffer, img_format ) the_image = iReader.read() # the_image = the_image0.scaledToWidth(figure_width) # save the image in a file # imageFileName = "image" + str(self.image_counter) + "." + img_format self.image_data_dict[imageFileName] = imgdata # self.image_counter +=1 imageFormat = QTextImageFormat() imageFormat.setName(imageFileName) imageFormat.setWidth(image_width) self.image_dict[imageFileName] = the_image #insert the image in the text document text_doc = self._teditor.document() text_doc.addResource(QTextDocument.ImageResource, QUrl(imageFileName), the_image) def append_html_table_from_array(self, a, header_rows=0, precision = 3, caption = None, cmap = None): nrows = len(a) ncols = len(a[0]) result_string = "<table border=\"1\" cellspacing=\"0\" cellpadding=\"2\">\n" if caption != None: result_string += "<caption>%s</caption>\n" % caption r = 0 while r < header_rows: result_string += "<tr>" for c in range(ncols): if a[r][c] != "": # count following blank columns count = 1 while ((c+count) < len(a[r])) and (a[r][c+count] == "") : count += 1 val = a[r][c] if (type(val) == numpy.float64) or (type(val) == float): # @UndefinedVariable if precision != 999: val = round(val, precision) if count > 1: result_string +="<th colspan=%s>%s</th>" % (count, val) else: result_string += "<th>%s</th>" % val result_string +="</tr>\n" r += 1 while r < nrows: result_string += "<tr>" for c in range(ncols): val = a[r][c] if (cmap == None): fcolor = "#ffffff" elif (type(val) == int) or (type(val) == float) or (type(val) == numpy.float64): # @UndefinedVariable fcolor = cmap.color_from_val(val) else: fcolor = "#ffffff" if (val != "") or (c == 0): if (type(val) == numpy.float64) or (type(val) == float): # @UndefinedVariable if precision != 999: val = round(val, precision) count = 1 while ((c+count) < len(a[r])) and (a[r][c+count] == "") : count += 1 if count > 1: result_string +="<td colspan=%s bgcolor=%s>%s</td>" % (count, fcolor, val) else: result_string += "<td bgcolor=%s>%s</td>" % (fcolor, val) result_string +="</tr>\n" r += 1 result_string += "</table>\n" self.append_text(result_string) def create_empty_string_array(self, rows, cols): table_array = [] for r in range(rows): #@UnusedVariable the_row = [] for c in range(cols): #@UnusedVariable the_row.append("") table_array.append(the_row) return table_array def recurse_on_dict_headers(self, sdict, r, c, sorted_headers = None): if ((type(sdict) != dict) and (type(sdict) != OrderedDict)): return c + 1 else: if sorted_headers != None: sheaders = sorted_headers else: sheaders = sorted(sdict.keys()) for k in sheaders: self.table_array[r][c] = k c = self.recurse_on_dict_headers(sdict[k], r + 1, c) return c def recurse_to_find_size(self, sdict, r, c): if ((type(sdict) != dict) and (type(sdict) != OrderedDict)): return r, c + 1 else: rbiggest = r for k in sorted(sdict.keys()): rnew, c = self.recurse_to_find_size(sdict[k], r + 1, c) if rnew > rbiggest: rbiggest = rnew return rbiggest, c def recurse_on_dict(self, sdict, r, c, sorted_headers = None): if ((type(sdict) != dict) and (type(sdict) != OrderedDict)): self.table_array[r][c] = sdict return c + 1 else: if sorted_headers != None: sheaders = sorted_headers else: sheaders = sorted(sdict.keys()) for k in sheaders: c = self.recurse_on_dict(sdict[k], r, c) return c def convert_structured_dicts_to_array(self, sdict, sorted_keys = None, sorted_headers = None): header_levels, ncols = self.recurse_to_find_size(sdict[sdict.keys()[0]], 0, 0) nrows = header_levels + len(sdict.keys()) self.table_array = self.create_empty_string_array(nrows, ncols) self.recurse_on_dict_headers(sdict[sdict.keys()[0]], 0, 0, sorted_headers) if sorted_keys != None: key_list = sorted_keys else: key_list = sdict.keys() r = header_levels for entry in key_list: c = 0 self.table_array[r][0] = entry self.recurse_on_dict(sdict[entry], r, c, sorted_headers = sorted_headers) r += 1 return self.table_array def append_html_table_from_dicts(self, sdict, header_rows = 1, title = None, sorted_keys = None, precision = 3, cmap = None, sorted_headers = None): the_array = self.convert_structured_dicts_to_array(sdict, sorted_keys, sorted_headers = sorted_headers) self.append_html_table_from_array(the_array, header_rows, caption = title, precision = precision, cmap = cmap) def append_table(self, rows, cols, border_style = QTextFrameFormat.BorderStyle_Solid): tformat = QTextTableFormat() tformat.setBorderStyle(border_style) cursor= self._teditor.textCursor() cursor.movePosition(QTextCursor.End) table = cursor.insertTable(rows, cols, tformat) return table def fill_table_cell(self, row, col, table, text): cptr = table.cellAt(row, col).firstCursorPosition() cptr.insertText(text) def save_as_html(self): fname = QFileDialog.getSaveFileName()[0] fdirectoryname = os.path.dirname(fname) # fdirectoryname = QFileDialog.getExistingDirectory() # print fdirectoryname # fname = fdirectoryname + "/report.html" text_doc = self._teditor.document() f = open(fname, 'w') f.write(text_doc.toHtml()) f.close() for imageFileName in self.image_dict.keys(): full_image_path = fdirectoryname + "/" + imageFileName iWriter = QImageWriter(full_image_path, img_format) iWriter.write(self.image_dict[imageFileName])