如何使项目视图在PyQt中呈现丰富(html)文本? [英] How to make item view render rich (html) text in PyQt?

查看:202
本文介绍了如何使项目视图在PyQt中呈现丰富(html)文本?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试从 python中的这个线程

 从PyQt4.QtCore import导入sys 
*
来自PyQt4.QtGui import *

__data__ = [
Lorem ipsum dolor sit amet,consectetur adipisicing elit,sed do eiusmod tempor incididunt ut labore et dolore magna aliqua。,
$ en $$$$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ 异教徒不要妄想,不要吝啬,unt untunt unt unt unt unt
]

def get_html_box(text):
return'''< table border =0width =100%>< tr width =100 %valign =top>
< td width =1%>< img src =softwarecenter.png/>< / td>
< td>< table border =0width =100%height =100%>
< tr>< td>< b>< a href =http://www.google.com> titolo< / a>< / b>< / td>< ; / tr>
< tr>< td> {0}< / td>< / tr>< tr>< td align =right> 88/88/8888,88:88< td>< / tr>
< / table>< / td>< / tr>< / table>'''格式(文本)

class HTMLDelegate(QStyledItemDelegate):

def paint(self,painter,option,index):
model = index.model()
record = model.listdata [index.row()]
doc = QTextDocument (self)
doc.setHtml(get_html_box(record))
doc.setTextWidth(option.rect.width())
painter.save()
ctx = QAbstractTextDocumentLayout.PaintContext ()
ctx.clip = QRectF(0,option.rect.top(),option.rect.width(),option.rect.height())
dl = doc.documentLayout()
dl.draw(painter,ctx)
painter.restore()

def sizeHint(self,option,index):
model = index.model()
record = model.listdata [index.row()]
doc = QTextDocument(self)
doc.setHtml(get_html_box(record))
doc.setTextWidth(option.rect。 width())
return Q size(doc.idealWidth(),doc.size()。height())

class MyListModel(QAbstractListModel):

def __init __(self,parent = None,* args):
super(MyListModel,self).__ init __(parent,* args)
self.listdata = __data__

def rowCount(self,parent = QModelIndex()):
return len(self.listdata)

def data(self,index,role = Qt.DisplayRole):
return index.isValid()和QVariant(self.listdata [ index.row()])或QVariant()

class MyWindow(QWidget):

def __init __(self,* args):
super(MyWindow,自我).__ init __(* args)
#listview
self.lv = QListView()
self.lv.setModel(MyListModel(self))
self.lv.setItemDelegate HTMLDelegate(self))
self.lv.setResizeMode(QListView.Adjust)
#layout
layout = QVBoxLayout()
layout.addWidget(self.lv)
self.setLayout(layout)

如果__name__ == __main__:
app = QApplication(sys.argv)
w = MyWindow()
w.show()
sys.exit(app.exec_())$ b $元素的大小和位置不正确计算我猜想,也许是因为我根本不了解所有风格相关的部分。从原代码。
有人可以帮助我吗?

解决方案

代码不符合所需的目标绘图区域( option.rect ):

  ctx.clip = QRectF(0,option.rect。 top(),option.rect.width(),option.rect.height())

以上剪贴指定区域的 QTextDocument 部分。你真的想翻译画家,以便它开始在矩形的 topLeft()上绘画,然后扩展指定的宽度和高度。由于 documentLayout()假设画家处于原始位置(即在应该绘制的位置),这是修正:

  def paint(self,painter,option,index):
model = index.model()
record = model.listdata [index.row ()]
doc = QTextDocument(self)
doc.setHtml(get_html_box(record))
doc.setTextWidth(option.rect.width())
ctx = QAbstractTextDocumentLayout。 PaintContext()

painter.save()
painter.translate(option.rect.topLeft());
painter.setClipRect(option.rect.translated(-option.rect.topLeft())
dl = doc.documentLayout()
dl.draw(painter,ctx)
painter.restore()


I'm trying to translate code from this thread in python:

    import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *

__data__ = [
        "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
        "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.",
        "Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.",
        "Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
    ]

def get_html_box(text):
    return '''<table border="0" width="100%"><tr width="100%" valign="top">
        <td width="1%"><img src="softwarecenter.png"/></td>
        <td><table border="0" width="100%" height="100%">
        <tr><td><b><a href="http://www.google.com">titolo</a></b></td></tr>
        <tr><td>{0}</td></tr><tr><td align="right">88/88/8888, 88:88</td></tr>
        </table></td></tr></table>'''.format(text)

class HTMLDelegate(QStyledItemDelegate):

    def paint(self, painter, option, index):
        model = index.model()
        record = model.listdata[index.row()]
        doc = QTextDocument(self)
        doc.setHtml(get_html_box(record))
        doc.setTextWidth(option.rect.width())
        painter.save()
        ctx = QAbstractTextDocumentLayout.PaintContext()
        ctx.clip = QRectF(0, option.rect.top(), option.rect.width(), option.rect.height())
        dl = doc.documentLayout()
        dl.draw(painter, ctx)
        painter.restore()

    def sizeHint(self, option, index):
        model = index.model()
        record = model.listdata[index.row()]
        doc = QTextDocument(self)
        doc.setHtml(get_html_box(record))
        doc.setTextWidth(option.rect.width())
        return QSize(doc.idealWidth(), doc.size().height())

class MyListModel(QAbstractListModel):

    def __init__(self, parent=None, *args):
        super(MyListModel, self).__init__(parent, *args)
        self.listdata = __data__

    def rowCount(self, parent=QModelIndex()):
        return len(self.listdata)

    def data(self, index, role=Qt.DisplayRole):
        return index.isValid() and QVariant(self.listdata[index.row()]) or QVariant()

class MyWindow(QWidget):

    def __init__(self, *args):
        super(MyWindow, self).__init__(*args)
        # listview
        self.lv = QListView()
        self.lv.setModel(MyListModel(self))
        self.lv.setItemDelegate(HTMLDelegate(self))
        self.lv.setResizeMode(QListView.Adjust)
        # layout
        layout = QVBoxLayout()
        layout.addWidget(self.lv)
        self.setLayout(layout)

if __name__ == "__main__":
    app = QApplication(sys.argv)
    w = MyWindow()
    w.show()
    sys.exit(app.exec_())

Element's size and position are not calculated correctly I guess, perhaps because I haven't understand at all the style related parts from original code. Can someone help me?

解决方案

The code doesn't respect the desired target drawing area (option.rect):

ctx.clip = QRectF(0, option.rect.top(), option.rect.width(), option.rect.height())

The above clips the portion of the QTextDocument drawn to the specified region. You really want to translate the painter so that the it starts painting at the topLeft() of the rectangle and then extends for the specified width and height. Since documentLayout() assumes the painter is at the origin (i.e. in the position where it should draw), this is the fix:

def paint(self, painter, option, index):
    model = index.model()
    record = model.listdata[index.row()]
    doc = QTextDocument(self)
    doc.setHtml(get_html_box(record))
    doc.setTextWidth(option.rect.width())
    ctx = QAbstractTextDocumentLayout.PaintContext()

    painter.save()
    painter.translate(option.rect.topLeft());
    painter.setClipRect(option.rect.translated(-option.rect.topLeft()))
    dl = doc.documentLayout()
    dl.draw(painter, ctx)
    painter.restore()

这篇关于如何使项目视图在PyQt中呈现丰富(html)文本?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆