class TextViewer(QWidget): def __init__(self, page, *args, **kwargs): self.page = page super(TextViewer, self).__init__(*args, **kwargs) self._document = QTextDocument(self) self._document.setUseDesignMetrics(True) self._page_number = 0 self.__offset_top = 0 def document(self): return self._document def setHtml(self, html): self._html = html self._updateHtml() def _offset_top(self): # FIXME the top offset is only on the first page, but this is ugly if self._page_number == 0: self.__offset_top = self.page.height() - self.height() return self.__offset_top def _updateHtml(self): css = textwrap.dedent(""" <style type="text/css"> tr.header {background: #BBB} tr.even {background: #CCC} tr.odd {background: #FFF} div.markdown {margin-top: %(margin)dpx} </style> """).strip() # make room for the "header" widgets css = css % {"margin": self._offset_top()} # print("css = %s" % css) html = '%s\n<div class="markdown">%s<span>' % (css, self._html) # print("setHtml <- %s" % html) self._document.setDefaultFont(self.font()) self._document.setHtml(html) def resizeEvent(self, resize_event): size = self.page.size() #print("setPageSize <- %s" % size) #old_size = self._document.pageSize() new_size = QSizeF(size.width(), size.height()) self._document.setPageSize(new_size) #print("self.size = %s" % self.size()) self._updateHtml() def paintEvent(self, paint_event): painter = QPainter(self) if self._page_number == 0: painter.setClipRect(QRectF(0, 0, self.page.width(), self.page.height()-self._offset_top())) painter.translate(0, -self._offset_top()) else: painter.setClipRect(QRectF(0, 0, self.page.width(), self.page.height())) height = self.page.height() painter.translate(0, -self._page_number*height) self._document.drawContents(painter) def pageCount(self): return self._document.pageCount() def setPageNumber(self, num): print("setPageNumber <- %s" % num) self._page_number = num self.update() def pageNumber(self): return self._page_number