import sys from PyQt4 import QtGui, QtCore from PyQt4.QtCore import Qt from ext import * class Main(QtGui.QMainWindow): def __init__(self, app, parent = None): QtGui.QMainWindow.__init__(self,parent) self.app = app self.filename = "" self.changesSaved = True self.pageCount = 0 self.pageCurr = 0 self.pageHeight = 841 self.lastDocumentHeight = self.pageHeight self.documentMargin = 50 self.initUI() def initToolbar(self): self.newAction = QtGui.QAction(QtGui.QIcon("icons/new.png"),"New",self) self.newAction.setShortcut("Ctrl+N") self.newAction.setStatusTip("Create a new document from scratch.") self.newAction.triggered.connect(self.new) self.openAction = QtGui.QAction(QtGui.QIcon("icons/open.png"),"Open file",self) self.openAction.setStatusTip("Open existing document") self.openAction.setShortcut("Ctrl+O") self.openAction.triggered.connect(self.open) self.saveAction = QtGui.QAction(QtGui.QIcon("icons/save.png"),"Save",self) self.saveAction.setStatusTip("Save document") self.saveAction.setShortcut("Ctrl+S") self.saveAction.triggered.connect(self.save) self.printAction = QtGui.QAction(QtGui.QIcon("icons/print.png"),"Print document",self) self.printAction.setStatusTip("Print document") self.printAction.setShortcut("Ctrl+P") self.printAction.triggered.connect(self.printHandler) self.previewAction = QtGui.QAction(QtGui.QIcon("icons/preview.png"),"Page view",self) self.previewAction.setStatusTip("Preview page before printing") self.previewAction.setShortcut("Ctrl+Shift+P") self.previewAction.triggered.connect(self.preview) self.findAction = QtGui.QAction(QtGui.QIcon("icons/find.png"),"Find and replace",self) self.findAction.setStatusTip("Find and replace words in your document") self.findAction.setShortcut("Ctrl+F") self.findAction.triggered.connect(find.Find(self).show) self.cutAction = QtGui.QAction(QtGui.QIcon("icons/cut.png"),"Cut to clipboard",self) self.cutAction.setStatusTip("Delete and copy text to clipboard") self.cutAction.setShortcut("Ctrl+X") self.cutAction.triggered.connect(self.text.cut) self.copyAction = QtGui.QAction(QtGui.QIcon("icons/copy.png"),"Copy to clipboard",self) self.copyAction.setStatusTip("Copy text to clipboard") self.copyAction.setShortcut("Ctrl+C") self.copyAction.triggered.connect(self.text.copy) self.pasteAction = QtGui.QAction(QtGui.QIcon("icons/paste.png"),"Paste from clipboard",self) self.pasteAction.setStatusTip("Paste text from clipboard") self.pasteAction.setShortcut("Ctrl+V") self.pasteAction.triggered.connect(self.text.paste) self.undoAction = QtGui.QAction(QtGui.QIcon("icons/undo.png"),"Undo last action",self) self.undoAction.setStatusTip("Undo last action") self.undoAction.setShortcut("Ctrl+Z") self.undoAction.triggered.connect(self.text.undo) self.redoAction = QtGui.QAction(QtGui.QIcon("icons/redo.png"),"Redo last undone thing",self) self.redoAction.setStatusTip("Redo last undone thing") self.redoAction.setShortcut("Ctrl+Y") self.redoAction.triggered.connect(self.text.redo) dateTimeAction = QtGui.QAction(QtGui.QIcon("icons/calender.png"),"Insert current date/time",self) dateTimeAction.setStatusTip("Insert current date/time") dateTimeAction.setShortcut("Ctrl+D") dateTimeAction.triggered.connect(datetime.DateTime(self).show) wordCountAction = QtGui.QAction(QtGui.QIcon("icons/count.png"),"See word/symbol count",self) wordCountAction.setStatusTip("See word/symbol count") wordCountAction.setShortcut("Ctrl+W") wordCountAction.triggered.connect(self.wordCount) tableAction = QtGui.QAction(QtGui.QIcon("icons/table.png"),"Insert table",self) tableAction.setStatusTip("Insert table") tableAction.setShortcut("Ctrl+T") tableAction.triggered.connect(table.Table(self).show) imageAction = QtGui.QAction(QtGui.QIcon("icons/image.png"),"Insert image",self) imageAction.setStatusTip("Insert image") imageAction.setShortcut("Ctrl+Shift+I") imageAction.triggered.connect(self.insertImage) bulletAction = QtGui.QAction(QtGui.QIcon("icons/bullet.png"),"Insert bullet List",self) bulletAction.setStatusTip("Insert bullet list") bulletAction.setShortcut("Ctrl+Shift+B") bulletAction.triggered.connect(self.bulletList) numberedAction = QtGui.QAction(QtGui.QIcon("icons/number.png"),"Insert numbered List",self) numberedAction.setStatusTip("Insert numbered list") numberedAction.setShortcut("Ctrl+Shift+L") numberedAction.triggered.connect(self.numberList) linkAction = QtGui.QAction(QtGui.QIcon("icons/link.png"),"Insert hyperlink",self) linkAction.setStatusTip("Insert hyperlink") linkAction.setShortcut("Ctrl+H") # Must use lambda, otherwise text isn't updated? linkAction.triggered.connect(lambda: link.Link(self).show()) self.toolbar = self.addToolBar("Options") self.toolbar.addAction(self.newAction) self.toolbar.addAction(self.openAction) self.toolbar.addAction(self.saveAction) self.toolbar.addSeparator() self.toolbar.addAction(self.printAction) self.toolbar.addAction(self.previewAction) self.toolbar.addSeparator() self.toolbar.addAction(self.cutAction) self.toolbar.addAction(self.copyAction) self.toolbar.addAction(self.pasteAction) self.toolbar.addAction(self.undoAction) self.toolbar.addAction(self.redoAction) self.toolbar.addSeparator() self.toolbar.addAction(self.findAction) self.toolbar.addAction(dateTimeAction) self.toolbar.addAction(wordCountAction) self.toolbar.addAction(tableAction) self.toolbar.addAction(imageAction) self.toolbar.addAction(linkAction) self.toolbar.addSeparator() self.toolbar.addAction(bulletAction) self.toolbar.addAction(numberedAction) self.addToolBarBreak() def initFormatbar(self): fontBox = QtGui.QFontComboBox(self) fontBox.currentFontChanged.connect(lambda font: self.text.setCurrentFont(font)) fontSize = QtGui.QSpinBox(self) # Will display " pt" after each value fontSize.setSuffix(" pt") fontSize.valueChanged.connect(lambda size: self.text.setFontPointSize(size)) fontSize.setValue(14) fontColor = QtGui.QAction(QtGui.QIcon("icons/font-color.png"),"Change font color",self) fontColor.triggered.connect(self.fontColorChanged) boldAction = QtGui.QAction(QtGui.QIcon("icons/bold.png"),"Bold",self) boldAction.triggered.connect(self.bold) italicAction = QtGui.QAction(QtGui.QIcon("icons/italic.png"),"Italic",self) italicAction.triggered.connect(self.italic) underlAction = QtGui.QAction(QtGui.QIcon("icons/underline.png"),"Underline",self) underlAction.triggered.connect(self.underline) strikeAction = QtGui.QAction(QtGui.QIcon("icons/strike.png"),"Strike-out",self) strikeAction.triggered.connect(self.strike) superAction = QtGui.QAction(QtGui.QIcon("icons/superscript.png"),"Superscript",self) superAction.triggered.connect(self.superScript) subAction = QtGui.QAction(QtGui.QIcon("icons/subscript.png"),"Subscript",self) subAction.triggered.connect(self.subScript) alignLeft = QtGui.QAction(QtGui.QIcon("icons/align-left.png"),"Align left",self) alignLeft.triggered.connect(self.alignLeft) alignCenter = QtGui.QAction(QtGui.QIcon("icons/align-center.png"),"Align center",self) alignCenter.triggered.connect(self.alignCenter) alignRight = QtGui.QAction(QtGui.QIcon("icons/align-right.png"),"Align right",self) alignRight.triggered.connect(self.alignRight) alignJustify = QtGui.QAction(QtGui.QIcon("icons/align-justify.png"),"Align justify",self) alignJustify.triggered.connect(self.alignJustify) indentAction = QtGui.QAction(QtGui.QIcon("icons/indent.png"),"Indent Area",self) indentAction.setShortcut("Ctrl+Tab") indentAction.triggered.connect(self.indent) dedentAction = QtGui.QAction(QtGui.QIcon("icons/dedent.png"),"Dedent Area",self) dedentAction.setShortcut("Shift+Tab") dedentAction.triggered.connect(self.dedent) backColor = QtGui.QAction(QtGui.QIcon("icons/highlight.png"),"Change background color",self) backColor.triggered.connect(self.highlight) self.formatbar = self.addToolBar("Format") self.formatbar.addWidget(fontBox) self.formatbar.addWidget(fontSize) self.formatbar.addSeparator() self.formatbar.addAction(fontColor) self.formatbar.addAction(backColor) self.formatbar.addSeparator() self.formatbar.addAction(boldAction) self.formatbar.addAction(italicAction) self.formatbar.addAction(underlAction) self.formatbar.addAction(strikeAction) self.formatbar.addAction(superAction) self.formatbar.addAction(subAction) self.formatbar.addSeparator() self.formatbar.addAction(alignLeft) self.formatbar.addAction(alignCenter) self.formatbar.addAction(alignRight) self.formatbar.addAction(alignJustify) self.formatbar.addSeparator() self.formatbar.addAction(indentAction) self.formatbar.addAction(dedentAction) def initMenubar(self): menubar = self.menuBar() file = menubar.addMenu("File") edit = menubar.addMenu("Edit") view = menubar.addMenu("View") # Add the most important actions to the menubar file.addAction(self.newAction) file.addAction(self.openAction) file.addAction(self.saveAction) file.addAction(self.printAction) file.addAction(self.previewAction) edit.addAction(self.undoAction) edit.addAction(self.redoAction) edit.addAction(self.cutAction) edit.addAction(self.copyAction) edit.addAction(self.pasteAction) edit.addAction(self.findAction) # Toggling actions for the various bars toolbarAction = QtGui.QAction("Toggle Toolbar",self) toolbarAction.triggered.connect(self.toggleToolbar) formatbarAction = QtGui.QAction("Toggle Formatbar",self) formatbarAction.triggered.connect(self.toggleFormatbar) statusbarAction = QtGui.QAction("Toggle Statusbar",self) statusbarAction.triggered.connect(self.toggleStatusbar) view.addAction(toolbarAction) view.addAction(formatbarAction) view.addAction(statusbarAction) def initDocument(self): self.printer = QtGui.QPrinter() # Set everything to zero because margin is set by the documents # margin (otherwise the printer has an offset) self.printer.setPageMargins(0,0,0,0,QtGui.QPrinter.DevicePixel) self.text = QtGui.QTextEdit(self) self.text.setStyleSheet("background-color: #FFFFFF;") # Get rid of ugly border self.text.setFrameShape(QtGui.QFrame.NoFrame) # Good A4 width self.text.setFixedWidth(595) self.text.setMinimumHeight(self.pageHeight) # Set the tab stop width to around 33 pixels which is # more or less 8 spaces self.text.setTabStopWidth(33) # Disable scroll bar self.text.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) doc = self.text.document() doc.setPageSize(QtCore.QSizeF(595,self.pageHeight)) # Set initial margin rootFrame = doc.rootFrame() fmt = rootFrame.frameFormat() fmt.setMargin(self.documentMargin) rootFrame.setFrameFormat(fmt) # Container widget that holds page container = QtGui.QWidget(self) container.setStyleSheet("background-color: #A0A0A0;") # Layout for container layout = QtGui.QGridLayout(self) # Empty widget for spacing layout.addWidget(QtGui.QWidget(),0,0) # Add QTextEdit to layout layout.addWidget(self.text,1,0) # Set layout to container container.setLayout(layout) # Put container into a scroll area so that # the user can scroll down to see all the pages self.scrollArea = QtGui.QScrollArea(self) self.scrollArea.setWidget(container) self.scrollArea.setWidgetResizable(True) # Align the scrollArea's widget in the center self.scrollArea.setAlignment(Qt.AlignHCenter) # Make the scrollArea take up the whole space of # the MainWindow self.setCentralWidget(self.scrollArea) # Connect documentSizeChanged signal to handler, to resize QTextEdit and scroll down self.text.document().documentLayout().documentSizeChanged.connect(self.handleDocumentSize) # If the cursor position changes, call the function that displays # the line and column number self.text.cursorPositionChanged.connect(self.cursorPosition) # We need our own context menu for tables self.text.setContextMenuPolicy(Qt.CustomContextMenu) self.text.customContextMenuRequested.connect(self.context) # To monitor unsaved changes self.text.textChanged.connect(self.changed) def initStatus(self): self.status = self.statusBar() self.status.setStyleSheet("background-color: #A0A0A0;") self.pageCountLabel = QtGui.QLabel("",self) self.status.addPermanentWidget(self.pageCountLabel) self.status.resize(400,50) # Initialize value for cursor position self.cursorPosition() def initUI(self): self.initDocument() self.initToolbar() self.initFormatbar() self.initMenubar() self.initStatus() self.setMinimumSize(995,900) self.move(450,25) self.setWindowTitle("Writer") self.setWindowIcon(QtGui.QIcon("icons/icon.png")) def handleDocumentSize(self,size): height = size.height() if height > self.pageHeight: self.text.setFixedHeight(height) self.scrollArea.verticalScrollBar().setValue(height) if height > self.lastDocumentHeight and height > (self.pageCount + 1) * self.pageHeight: self.pageCount += 1 elif height < self.lastDocumentHeight and height < self.pageCount * self.pageHeight: self.pageCount -= 1 self.lastDocumentHeight = height def changed(self): self.changesSaved = False def closeEvent(self,event): if self.changesSaved: event.accept() else: popup = QtGui.QMessageBox(self) popup.setIcon(QtGui.QMessageBox.Warning) popup.setText("The document has been modified") popup.setInformativeText("Do you want to save your changes?") popup.setStandardButtons(QtGui.QMessageBox.Save | QtGui.QMessageBox.Cancel | QtGui.QMessageBox.Discard) popup.setDefaultButton(QtGui.QMessageBox.Save) answer = popup.exec_() if answer == QtGui.QMessageBox.Save: self.save() elif answer == QtGui.QMessageBox.Discard: event.accept() else: event.ignore() def context(self,pos): # Grab the cursor cursor = self.text.textCursor() # Grab the current table, if there is one table = cursor.currentTable() # Grab current URL, if any hyperlink = link.currentHyperlink(cursor) # Above will return 0 if there is no current table, in which case # we call the normal context menu. If there is a table, we create # our own context menu specific to table interaction if table or hyperlink: # Convert the widget coordinates into global coordinates pos = self.text.mapToGlobal(pos) # Create new menu menu = QtGui.QMenu(self.text) # Add actions for hyperlinks if available if hyperlink: openAction = QtGui.QAction("Open hyperlink",self) openAction.triggered.connect(lambda: link.openHyperlink(hyperlink)) copyAction = QtGui.QAction("Copy hyperlink",self) copyAction.triggered.connect(lambda: self.app.clipboard().setText(hyperlink)) removeAction = QtGui.QAction("Remove hyperlink",self) removeAction.triggered.connect(lambda: link.removeHyperlink(cursor)) editAction = QtGui.QAction("Edit hyperlink",self) editAction.triggered.connect(lambda: link.Link(self,True).show()) menu.addAction(openAction) menu.addAction(copyAction) menu.addAction(removeAction) menu.addAction(editAction) menu.addSeparator() if table: appendRowAction = QtGui.QAction("Append row",self) appendRowAction.triggered.connect(lambda: table.appendRows(1)) appendColAction = QtGui.QAction("Append column",self) appendColAction.triggered.connect(lambda: table.appendColumns(1)) removeRowAction = QtGui.QAction("Remove row",self) removeRowAction.triggered.connect(self.removeRow) removeColAction = QtGui.QAction("Remove column",self) removeColAction.triggered.connect(self.removeCol) insertRowAction = QtGui.QAction("Insert row",self) insertRowAction.triggered.connect(self.insertRow) insertColAction = QtGui.QAction("Insert column",self) insertColAction.triggered.connect(self.insertCol) mergeAction = QtGui.QAction("Merge cells",self) mergeAction.triggered.connect(lambda: table.mergeCells(cursor)) # Only allow merging if there is a selection if not cursor.hasSelection(): mergeAction.setEnabled(False) splitAction = QtGui.QAction("Split cells",self) cell = table.cellAt(cursor) # Only allow splitting if the current cell is larger # than a normal cell if cell.rowSpan() > 1 or cell.columnSpan() > 1: splitAction.triggered.connect(lambda: table.splitCell(cell.row(),cell.column(),1,1)) else: splitAction.setEnabled(False) menu.addAction(appendRowAction) menu.addAction(appendColAction) menu.addSeparator() menu.addAction(removeRowAction) menu.addAction(removeColAction) menu.addSeparator() menu.addAction(insertRowAction) menu.addAction(insertColAction) menu.addSeparator() menu.addAction(mergeAction) menu.addAction(splitAction) menu.exec_(pos) else: event = QtGui.QContextMenuEvent(QtGui.QContextMenuEvent.Mouse,QtCore.QPoint()) self.text.contextMenuEvent(event) def removeRow(self): # Grab the cursor cursor = self.text.textCursor() # Grab the current table (we assume there is one, since # this is checked before calling) table = cursor.currentTable() # Get the current cell cell = table.cellAt(cursor) # Delete the cell's row table.removeRows(cell.row(),1) def removeCol(self): # Grab the cursor cursor = self.text.textCursor() # Grab the current table (we assume there is one, since # this is checked before calling) table = cursor.currentTable() # Get the current cell cell = table.cellAt(cursor) # Delete the cell's column table.removeColumns(cell.column(),1) def insertRow(self): # Grab the cursor cursor = self.text.textCursor() # Grab the current table (we assume there is one, since # this is checked before calling) table = cursor.currentTable() # Get the current cell cell = table.cellAt(cursor) # Insert a new row at the cell's position table.insertRows(cell.row(),1) def insertCol(self): # Grab the cursor cursor = self.text.textCursor() # Grab the current table (we assume there is one, since # this is checked before calling) table = cursor.currentTable() # Get the current cell cell = table.cellAt(cursor) # Insert a new row at the cell's position table.insertColumns(cell.column(),1) def toggleToolbar(self): state = self.toolbar.isVisible() # Set the visibility to its inverse self.toolbar.setVisible(not state) def toggleFormatbar(self): state = self.formatbar.isVisible() # Set the visibility to its inverse self.formatbar.setVisible(not state) def toggleStatusbar(self): state = self.status.isVisible() # Set the visibility to its inverse self.status.setVisible(not state) def new(self): spawn = Main(self.app) spawn.show() def open(self): # Get filename and show only .writer files self.filename = QtGui.QFileDialog.getOpenFileName(self, 'Open File',".","(*.writer)") if self.filename: with open(self.filename,"rt",encoding="utf-8") as file: self.text.setText(file.read()) def save(self): # Only open dialog if there is no filename yet if not self.filename: self.filename = QtGui.QFileDialog.getSaveFileName(self, 'Save File') if self.filename: # Append extension if not there yet if not self.filename.endswith(".writer"): self.filename += ".writer" # We just store the contents of the text file along with the # format in html, which Qt does in a very nice way for us with open(self.filename,"wt", encoding="utf-8") as file: file.write(self.text.toHtml()) self.changesSaved = True def preview(self): # Open preview dialog preview = QtGui.QPrintPreviewDialog(self.printer) # If a print is requested, open print dialog preview.paintRequested.connect(lambda p: self.text.print_(p)) preview.exec_() def printHandler(self): # Open printing dialog dialog = QtGui.QPrintDialog(self.printer) if dialog.exec_() == QtGui.QDialog.Accepted: self.text.document().print_(dialog.printer()) def cursorPosition(self): cursor = self.text.textCursor() # Mortals like 1-indexed things line = cursor.blockNumber() + 1 col = cursor.columnNumber() + 1 self.status.showMessage("Line: {} | Column: {}".format(line,col)) # Calcule current page number from cursorPosition + margin for top + 10 to add padding for the space # above the document self.pageCurr = int((self.text.cursorRect().center().y() + self.documentMargin + 10) / self.pageHeight) # Set cursorPosLabel with current page number self.pageCountLabel.setText("Page {} of {}".format(self.pageCurr + 1,self.pageCount + 1)) def wordCount(self): wc = wordcount.WordCount(self) wc.getText() wc.show() def insertImage(self): # Get image file name filename = QtGui.QFileDialog.getOpenFileName(self, 'Insert image',".","Images (*.png *.xpm *.jpg *.bmp *.gif)") if filename: # Create image object image = QtGui.QImage(filename) # Error if unloadable if image.isNull(): popup = QtGui.QMessageBox(QtGui.QMessageBox.Critical, "Image load error", "Could not load image file!", QtGui.QMessageBox.Ok, self) popup.show() else: cursor = self.text.textCursor() cursor.insertImage(image,filename) def fontColorChanged(self): # Get a color from the text dialog color = QtGui.QColorDialog.getColor() # Set it as the new text color self.text.setTextColor(color) def highlight(self): color = QtGui.QColorDialog.getColor() self.text.setTextBackgroundColor(color) def bold(self): if self.text.fontWeight() == QtGui.QFont.Bold: self.text.setFontWeight(QtGui.QFont.Normal) else: self.text.setFontWeight(QtGui.QFont.Bold) def italic(self): state = self.text.fontItalic() self.text.setFontItalic(not state) def underline(self): state = self.text.fontUnderline() self.text.setFontUnderline(not state) def strike(self): # Grab the text's format fmt = self.text.currentCharFormat() # Set the fontStrikeOut property to its opposite fmt.setFontStrikeOut(not fmt.fontStrikeOut()) # And set the next char format self.text.setCurrentCharFormat(fmt) def superScript(self): # Grab the current format fmt = self.text.currentCharFormat() # And get the vertical alignment property align = fmt.verticalAlignment() # Toggle the state if align == QtGui.QTextCharFormat.AlignNormal: fmt.setVerticalAlignment(QtGui.QTextCharFormat.AlignSuperScript) else: fmt.setVerticalAlignment(QtGui.QTextCharFormat.AlignNormal) # Set the new format self.text.setCurrentCharFormat(fmt) def subScript(self): # Grab the current format fmt = self.text.currentCharFormat() # And get the vertical alignment property align = fmt.verticalAlignment() # Toggle the state if align == QtGui.QTextCharFormat.AlignNormal: fmt.setVerticalAlignment(QtGui.QTextCharFormat.AlignSubScript) else: fmt.setVerticalAlignment(QtGui.QTextCharFormat.AlignNormal) # Set the new format self.text.setCurrentCharFormat(fmt) def alignLeft(self): self.text.setAlignment(Qt.AlignLeft) def alignRight(self): self.text.setAlignment(Qt.AlignRight) def alignCenter(self): self.text.setAlignment(Qt.AlignCenter) def alignJustify(self): self.text.setAlignment(Qt.AlignJustify) def indent(self): # Grab the cursor cursor = self.text.textCursor() if cursor.hasSelection(): # Store the current line/block number temp = cursor.blockNumber() # Move to the selection's end cursor.setPosition(cursor.anchor()) # Calculate range of selection diff = cursor.blockNumber() - temp direction = QtGui.QTextCursor.Up if diff > 0 else QtGui.QTextCursor.Down # Iterate over lines (diff absolute value) for n in range(abs(diff) + 1): # Move to start of each line cursor.movePosition(QtGui.QTextCursor.StartOfLine) # Insert tabbing cursor.insertText("\t") # And move back up cursor.movePosition(direction) # If there is no selection, just insert a tab else: cursor.insertText("\t") def handleDedent(self,cursor): cursor.movePosition(QtGui.QTextCursor.StartOfLine) # Grab the current line line = cursor.block().text() # If the line starts with a tab character, delete it if line.startswith("\t"): # Delete next character cursor.deleteChar() # Otherwise, delete all spaces until a non-space character is met else: for char in line[:8]: if char != " ": break cursor.deleteChar() def dedent(self): cursor = self.text.textCursor() if cursor.hasSelection(): # Store the current line/block number temp = cursor.blockNumber() # Move to the selection's last line cursor.setPosition(cursor.anchor()) # Calculate range of selection diff = cursor.blockNumber() - temp direction = QtGui.QTextCursor.Up if diff > 0 else QtGui.QTextCursor.Down # Iterate over lines for n in range(abs(diff) + 1): self.handleDedent(cursor) # Move up cursor.movePosition(direction) else: self.handleDedent(cursor) def bulletList(self): cursor = self.text.textCursor() # Insert bulleted list cursor.insertList(QtGui.QTextListFormat.ListDisc) def numberList(self): cursor = self.text.textCursor() # Insert list with numbers cursor.insertList(QtGui.QTextListFormat.ListDecimal) def main(): app = QtGui.QApplication(sys.argv) main = Main(app) main.show() sys.exit(app.exec_()) if __name__ == "__main__": main()