class QAbstractTextDocumentLayoutTest(UsesQApplication): objectType = QTextFormat.UserObject + 1 def foo(self): fmt = QTextCharFormat() fmt.setObjectType(QAbstractTextDocumentLayoutTest.objectType) cursor = self.textEdit.textCursor() cursor.insertText(py3k.unichr(0xfffc), fmt) self.textEdit.setTextCursor(cursor) self.textEdit.close() def testIt(self): self.textEdit = QTextEdit() self.textEdit.show() interface = Foo() self.textEdit.document().documentLayout().registerHandler( QAbstractTextDocumentLayoutTest.objectType, interface) QTimer.singleShot(0, self.foo) self.app.exec_() self.assertTrue(Foo.called)
class QAbstractTextDocumentLayoutTest(UsesQApplication): objectType = QTextFormat.UserObject + 1 def foo(self): fmt = QTextCharFormat() fmt.setObjectType(QAbstractTextDocumentLayoutTest.objectType) cursor = self.textEdit.textCursor() cursor.insertText(py3k.unichr(0xFFFC), fmt) self.textEdit.setTextCursor(cursor) self.textEdit.close() def testIt(self): self.textEdit = QTextEdit() self.textEdit.show() interface = Foo() self.textEdit.document().documentLayout().registerHandler(QAbstractTextDocumentLayoutTest.objectType, interface) QTimer.singleShot(0, self.foo) self.app.exec_() self.assertTrue(Foo.called)
def testRefcount(self): textedit = QTextEdit() textedit.setReadOnly(True) doc = textedit.document() cursor = QTextCursor(doc) cursor.insertText("PySide Rocks") ud = TestUserData({"Life": 42}) self.assertEqual(sys.getrefcount(ud), 2) cursor.block().setUserData(ud) self.assertEqual(sys.getrefcount(ud), 3) ud2 = cursor.block().userData() self.assertEqual(sys.getrefcount(ud), 4) self.udata = weakref.ref(ud, None) del ud, ud2 self.assertEqual(sys.getrefcount(self.udata()), 2)
def testRefcount(self): textedit = QTextEdit() textedit.setReadOnly(True) doc = textedit.document() cursor = QTextCursor(doc) cursor.insertText("PySide Rocks") ud = TestUserData({"Life": 42}) self.assertEqual(sys.getrefcount(ud), 2) cursor.block().setUserData(ud) self.assertEqual(sys.getrefcount(ud), 3) ud2 = cursor.block().userData() self.assertEqual(sys.getrefcount(ud), 4) self.udata = weakref.ref(ud, None) del ud, ud2 self.assertEqual(sys.getrefcount(self.udata()), 2)
def tesIterator(self): edit = QTextEdit() cursor = edit.textCursor() fmt = QTextCharFormat() frags = [] for i in range(10): fmt.setFontPointSize(i+10) frags.append("block%d"%i) cursor.insertText(frags[i], fmt) doc = edit.document() block = doc.begin() index = 0 for i in block: self.assertEqual(i.fragment().text(), frags[index]) index += 1
def tesIterator(self): edit = QTextEdit() cursor = edit.textCursor() fmt = QTextCharFormat() frags = [] for i in range(10): fmt.setFontPointSize(i + 10) frags.append("block%d" % i) cursor.insertText(frags[i], fmt) doc = edit.document() block = doc.begin() index = 0 for i in block: self.assertEqual(i.fragment().text(), frags[index]) index += 1
class RobocompDslGui(QMainWindow): def __init__(self, parent=None): super(RobocompDslGui, self).__init__(parent) self.setWindowTitle("Create new component") # self._idsl_paths = [] self._communications = { "implements": [], "requires": [], "subscribesTo": [], "publishes": [] } self._interfaces = {} self._cdsl_doc = CDSLDocument() self._command_process = QProcess() self._main_widget = QWidget() self._main_layout = QVBoxLayout() self.setCentralWidget(self._main_widget) self._name_layout = QHBoxLayout() self._name_line_edit = QLineEdit() self._name_line_edit.textEdited.connect(self.update_component_name) self._name_line_edit.setPlaceholderText("New component name") self._name_layout.addWidget(self._name_line_edit) self._name_layout.addStretch() # DIRECTORY SELECTION self._dir_line_edit = QLineEdit() # self._dir_line_edit.textEdited.connect(self.update_completer) self._dir_completer = QCompleter() self._dir_completer_model = QFileSystemModel() if os.path.isdir(ROBOCOMP_COMP_DIR): self._dir_line_edit.setText(ROBOCOMP_COMP_DIR) self._dir_completer_model.setRootPath(ROBOCOMP_COMP_DIR) self._dir_completer.setModel(self._dir_completer_model) self._dir_line_edit.setCompleter(self._dir_completer) self._dir_button = QPushButton("Select directory") self._dir_button.clicked.connect(self.set_output_directory) self._dir_layout = QHBoxLayout() self._dir_layout.addWidget(self._dir_line_edit) self._dir_layout.addWidget(self._dir_button) # LIST OF ROBOCOMP INTERFACES self._interface_list = QListWidget() self._interface_list.setSelectionMode( QAbstractItemView.ExtendedSelection) self._interface_list.itemSelectionChanged.connect( self.set_comunication) # LIST OF CONNECTION TyPES self._type_combo_box = QComboBox() self._type_combo_box.addItems( ["publishes", "implements", "subscribesTo", "requires"]) self._type_combo_box.currentIndexChanged.connect( self.reselect_existing) # BUTTON TO ADD A NEW CONNECTION # self._add_connection_button = QPushButton("Add") # self._add_connection_button.clicked.connect(self.add_new_comunication) self._add_connection_layout = QHBoxLayout() # self._add_connection_layout.addWidget(self._add_connection_button) self._language_combo_box = QComboBox() self._language_combo_box.addItems(["Python", "Cpp", "Cpp11"]) self._language_combo_box.currentIndexChanged.connect( self.update_language) self._add_connection_layout.addWidget(self._language_combo_box) self._add_connection_layout.addStretch() self._gui_check_box = QCheckBox() self._gui_check_box.stateChanged.connect(self.update_gui_selection) self._gui_label = QLabel("Use Qt GUI") self._add_connection_layout.addWidget(self._gui_label) self._add_connection_layout.addWidget(self._gui_check_box) # WIDGET CONTAINING INTERFACES AND TYPES self._selection_layout = QVBoxLayout() self._selection_layout.addWidget(self._type_combo_box) self._selection_layout.addWidget(self._interface_list) self._selection_layout.addLayout(self._add_connection_layout) self._selection_widget = QWidget() self._selection_widget.setLayout(self._selection_layout) # TEXT EDITOR WITH THE RESULTING CDSL CODE self._editor = QTextEdit(self) self._editor.setHtml("") self._document = self._editor.document() self._component_directory = None # SPLITTER WITH THE SELECTION AND THE CODE self._body_splitter = QSplitter(Qt.Horizontal) self._body_splitter.addWidget(self._selection_widget) self._body_splitter.addWidget(self._editor) self._body_splitter.setStretchFactor(0, 2) self._body_splitter.setStretchFactor(1, 9) # CREATION BUTTONS self._create_button = QPushButton("Create .cdsl") self._create_button.clicked.connect(self.write_cdsl_file) self._creation_layout = QHBoxLayout() self._creation_layout.addStretch() self._creation_layout.addWidget(self._create_button) self._console = QConsole() self._command_process.readyReadStandardOutput.connect( self._console.standard_output) self._command_process.readyReadStandardError.connect( self._console.error_output) # ADDING WIDGETS TO MAIN LAYOUT self._main_widget.setLayout(self._main_layout) self._main_layout.addLayout(self._name_layout) self._main_layout.addLayout(self._dir_layout) self._main_layout.addWidget(self._body_splitter) self._main_layout.addLayout(self._creation_layout) self._main_layout.addWidget(self._console) self.setMinimumSize(800, 500) self._editor.setText(self._cdsl_doc.generate_doc()) # self.editor->show(); # def update_completer(self, path): # print "update_completer %s"%path # info = QFileInfo(path) # if info.exists() and info.isDir(): # if not path.endswith(os.path.pathsep): # new_path = os.path.join(path, os.sep) # # self._dir_line_edit.setText(new_path) # all_dirs_output = [dI for dI in os.listdir(path) if os.path.isdir(os.path.join(path, dI))] # print all_dirs_output # self._dir_completer.complete() def load_idsl_files(self, fullpath=None): if fullpath is None: fullpath = ROBOCOMP_INTERFACES idsls_dir = os.path.join(ROBOCOMP_INTERFACES, "IDSLs") if os.path.isdir(idsls_dir): for full_filename in os.listdir(idsls_dir): file_name, file_extension = os.path.splitext(full_filename) if "idsl" in file_extension.lower(): full_idsl_path = os.path.join(idsls_dir, full_filename) # self._idsl_paths.append(os.path.join(idsls_dir,full_filename)) self.parse_idsl_file(full_idsl_path) self._interface_list.addItems(self._interfaces.keys()) def parse_idsl_file(self, fullpath): with open(fullpath, 'r') as fin: interface_name = None for line in fin: result = re.findall(r'^\s*interface\s+(\w+)\s*\{?\s*$', line, flags=re.MULTILINE) if len(result) > 0: interface_name = result[0] print("%s for idsl %s" % (interface_name, fullpath)) if interface_name is not None: self._interfaces[interface_name] = fullpath def add_new_comunication(self): interface_names = self._interface_list.selectedItems() com_type = str(self._type_combo_box.currentText()) for iface_name_item in interface_names: iface_name = str(iface_name_item.text()) self._communications[com_type].append(iface_name) idsl_full_path = self._interfaces[iface_name] idsl_full_filename = os.path.basename(idsl_full_path) self._cdsl_doc.add_comunication(com_type, iface_name) self._cdsl_doc.add_import(idsl_full_filename) self.update_editor() def set_comunication(self): interface_names = self._interface_list.selectedItems() com_type = str(self._type_combo_box.currentText()) self._communications[com_type] = [] self._cdsl_doc.clear_comunication(com_type) for iface_name_item in interface_names: iface_name = str(iface_name_item.text()) self._communications[com_type].append(iface_name) self._cdsl_doc.add_comunication(com_type, iface_name) self.update_imports() self.update_editor() def update_imports(self): self._cdsl_doc.clear_imports() for com_type in self._communications: for iface_name in self._communications[com_type]: idsl_full_path = self._interfaces[iface_name] idsl_full_filename = os.path.basename(idsl_full_path) self._cdsl_doc.add_import(idsl_full_filename) def update_language(self): language = self._language_combo_box.currentText() self._cdsl_doc.set_language(str(language)) self.update_editor() def update_gui_selection(self): checked = self._gui_check_box.isChecked() if checked: self._cdsl_doc.set_qui(True) else: self._cdsl_doc.set_qui(False) self.update_editor() def update_component_name(self, name): self._cdsl_doc.set_name(name) self.update_editor() def update_editor(self): self._editor.setText(self._cdsl_doc.generate_doc()) def set_output_directory(self): dir_set = False while not dir_set: dir = QFileDialog.getExistingDirectory( self, "Select Directory", ROBOCOMP_COMP_DIR, QFileDialog.ShowDirsOnly | QFileDialog.DontResolveSymlinks) if self.check_dir_is_empty(str(dir)): self._dir_line_edit.setText(dir) dir_set = True def write_cdsl_file(self): component_dir = str(self._dir_line_edit.text()) text = self._cdsl_doc.generate_doc() if not self._name_line_edit.text(): component_name, ok = QInputDialog.getText(self, 'No component name set', 'Enter component name:') if ok: self.update_component_name(component_name) self._name_line_edit.setText(component_name) else: return False if not os.path.exists(component_dir): if QMessageBox.Yes == QMessageBox.question( self, "Directory doesn't exist.", "Do you want create the directory %s?" % component_dir, QMessageBox.Yes | QMessageBox.No): os.makedirs(component_dir) else: QMessageBox.question( self, "Directory not exist", "Can't create a component witout a valid directory") return False file_path = os.path.join(component_dir, str(self._name_line_edit.text()) + ".cdsl") if os.path.exists(file_path): if QMessageBox.No == QMessageBox.question( self, "File already exists", "Do you want to overwrite?", QMessageBox.Yes | QMessageBox.No): return False with open(file_path, 'w') as the_file: the_file.write(text) self.execute_robocomp_cdsl() return True def execute_robocomp_cdsl(self): cdsl_file_path = os.path.join( str(self._dir_line_edit.text()), str(self._name_line_edit.text()) + ".cdsl") command = "python -u %s/robocompdsl.py %s %s" % ( ROBOCOMPDSL_DIR, cdsl_file_path, os.path.join(str(self._dir_line_edit.text()))) self._console.append_custom_text("%s\n" % command) self._command_process.start(command, QProcess.Unbuffered | QProcess.ReadWrite) def reselect_existing(self): com_type = self._type_combo_box.currentText() selected = self._communications[com_type] self._interface_list.clearSelection() for iface in selected: items = self._interface_list.findItems(iface, Qt.MatchFlag.MatchExactly) if len(items) > 0: item = items[0] item.setSelected(True) def check_dir_is_empty(self, dir_path): if len(os.listdir(dir_path)) > 0: msgBox = QMessageBox() msgBox.setWindowTitle("Directory not empty") msgBox.setText( "The selected directory is not empty.\n" "For a new Component you usually want a new directory.\n" "Do you want to use this directory anyway?") msgBox.setStandardButtons(QMessageBox.Yes) msgBox.addButton(QMessageBox.No) msgBox.setDefaultButton(QMessageBox.No) if msgBox.exec_() == QMessageBox.Yes: return True else: return False else: return 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')) 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 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])