在pyQt/pySide QTableWidget中显示LaTeX [英] Displaying LaTeX in pyQt/pySide QTableWidget

查看:118
本文介绍了在pyQt/pySide QTableWidget中显示LaTeX的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在表格标签上添加数学表达式(例如:2 ^ 3应该正确设置格式)

I would like to add mathematical expressions to the table labels (e.g.: 2^3 should be properly formatted)

这是一个简单的表格示例: http://thomas-cokelaer.info/blog /2012/10/pyqt4-example-of-tablewidget-usage/

Here is a simple example of a table: http://thomas-cokelaer.info/blog/2012/10/pyqt4-example-of-tablewidget-usage/

setHorizo​​ntalHeaderLabels仅接受字符串. 我想知道是否可以通过某种方式实现这种matplotlib方法: matplotlib-以Qt格式编写TeX

setHorizontalHeaderLabels accepts string, only. I wonder if is it possible to implement somehow this matplotlib approach: matplotlib - write TeX on Qt form

还有其他选择吗?

推荐答案

我还尝试了一段时间,以在 QTableWidget 的标题中显示复杂的标签.我可以通过重新实现 QHeaderView paintSection 方法并按照QTextDocument 手动绘制标签来做到这一点. ="https://forum.qt.io/topic/30598/solved-how-to-display-subscript-text-in-header-of-qtableview/5" rel ="noreferrer"> Qt中心上的线程.

I've also been trying for some time to display complex labels in the header of a QTableWidget. I was able to do it by reimplementing the paintSection method of a QHeaderView and painting manually the label with a QTextDocument as described in a thread on Qt Centre.

但是,与LaTex相比,该解决方案在一定程度上受到了限制.我认为尝试在OP中建议的方法可能是个好主意,即使用matplotlib的功能在PySide中渲染LaTex.

However, this solution was somewhat limited compared to what could be done with LaTex. I thought this could be a good idea to try the approach you suggested in your OP, i.e. using the capability of matplotlib to render LaTex in PySide.

此方法所需的第一件事是能够将matplotlib图形转换为易于在任何 QWidget 上绘制的格式.下面是一个函数,该函数将 mathTex表达式作为输入,并将其通过matplotlib转换为 QPixmap .

First thing that is required in this approach is to be able to convert matplotlib figure in a format that can be easily painted on any QWidget. Below is a function that take a mathTex expression as input and convert it through matplotlib to a QPixmap.

import sys
import matplotlib as mpl
from matplotlib.backends.backend_agg import FigureCanvasAgg
from PySide import QtGui, QtCore

def mathTex_to_QPixmap(mathTex, fs):

    #---- set up a mpl figure instance ----

    fig = mpl.figure.Figure()
    fig.patch.set_facecolor('none')
    fig.set_canvas(FigureCanvasAgg(fig))
    renderer = fig.canvas.get_renderer()

    #---- plot the mathTex expression ----

    ax = fig.add_axes([0, 0, 1, 1])
    ax.axis('off')
    ax.patch.set_facecolor('none')
    t = ax.text(0, 0, mathTex, ha='left', va='bottom', fontsize=fs)

    #---- fit figure size to text artist ----

    fwidth, fheight = fig.get_size_inches()
    fig_bbox = fig.get_window_extent(renderer)

    text_bbox = t.get_window_extent(renderer)

    tight_fwidth = text_bbox.width * fwidth / fig_bbox.width
    tight_fheight = text_bbox.height * fheight / fig_bbox.height

    fig.set_size_inches(tight_fwidth, tight_fheight)

    #---- convert mpl figure to QPixmap ----

    buf, size = fig.canvas.print_to_buffer()
    qimage = QtGui.QImage.rgbSwapped(QtGui.QImage(buf, size[0], size[1],
                                                  QtGui.QImage.Format_ARGB32))
    qpixmap = QtGui.QPixmap(qimage)

    return qpixmap

2.将QPixmaps绘制到QTableWidget的标题

下一步是在 QTableWidget 的标题中绘制 QPixmap .如下所示,我通过对 QTableWidget 进行子类化并重新实现 setHorizo​​ntalHeaderLabels 方法来实现此目的,该方法用于将标签的mathTex表达式转换为 QPixmap ,并将其作为列表传递给 QHeaderView 的子类.然后在 QHeaderView paintSection 方法的重新实现中绘制 QPixmap ,并将标题的高度设置为适合重新实现 sizeHint 方法的mathTex表达式.

2. Paint the QPixmaps to the header of a QTableWidget

The next step is to paint the QPixmap in the header of a QTableWidget. As shown below, I've done it by sub-classing QTableWidget and reimplementing the setHorizontalHeaderLabels method, which is used to convert the mathTex expressions for the labels into QPixmap and to pass it as a list to a subclass of QHeaderView. The QPixmap are then painted within a reimplementation of the paintSection method of QHeaderView and the height of the header is set up to fit the height of the mathTex expression in the reimplementation of the sizeHint methods.

class MyQTableWidget(QtGui.QTableWidget):   
    def __init__(self, parent=None):
        super(MyQTableWidget, self).__init__(parent)

        self.setHorizontalHeader(MyHorizHeader(self))

    def setHorizontalHeaderLabels(self, headerLabels, fontsize):

        qpixmaps = []
        indx = 0
        for labels in headerLabels:
            qpixmaps.append(mathTex_to_QPixmap(labels, fontsize))            
            self.setColumnWidth(indx, qpixmaps[indx].size().width() + 16)
            indx += 1

        self.horizontalHeader().qpixmaps = qpixmaps

        super(MyQTableWidget, self).setHorizontalHeaderLabels(headerLabels)


class MyHorizHeader(QtGui.QHeaderView):
    def __init__(self, parent):
        super(MyHorizHeader, self).__init__(QtCore.Qt.Horizontal, parent)

        self.setClickable(True)
        self.setStretchLastSection(True)

        self.qpixmaps = []

    def paintSection(self, painter, rect, logicalIndex):

        if not rect.isValid():
            return

        #------------------------------ paint section (without the label) ----

        opt = QtGui.QStyleOptionHeader()        
        self.initStyleOption(opt)

        opt.rect = rect
        opt.section = logicalIndex
        opt.text = ""

        #---- mouse over highlight ----

        mouse_pos = self.mapFromGlobal(QtGui.QCursor.pos())               
        if rect.contains(mouse_pos):
            opt.state |= QtGui.QStyle.State_MouseOver

        #---- paint ----

        painter.save()        
        self.style().drawControl(QtGui.QStyle.CE_Header, opt, painter, self)
        painter.restore()

        #------------------------------------------- paint mathText label ----

        qpixmap = self.qpixmaps[logicalIndex]

        #---- centering ----

        xpix = (rect.width() - qpixmap.size().width()) / 2. + rect.x()
        ypix = (rect.height() - qpixmap.size().height()) / 2.

        #---- paint ----

        rect = QtCore.QRect(xpix, ypix, qpixmap.size().width(),
                            qpixmap.size().height())
        painter.drawPixmap(rect, qpixmap)        

    def sizeHint(self):

        baseSize = QtGui.QHeaderView.sizeHint(self)

        baseHeight = baseSize.height()
        if len(self.qpixmaps):
            for pixmap in self.qpixmaps:
               baseHeight = max(pixmap.height() + 8, baseHeight)
        baseSize.setHeight(baseHeight)

        self.parentWidget().repaint()

        return baseSize

3.申请

下面是上述示例的简单应用示例.

3. Application

Below is an example of a simple application of the above.

if __name__ == '__main__':

    app = QtGui.QApplication(sys.argv)

    w = MyQTableWidget()
    w.verticalHeader().hide()

    headerLabels = [
        '$C_{soil}=(1 - n) C_m + \\theta_w C_w$',
        '$k_{soil}=\\frac{\\sum f_j k_j \\theta_j}{\\sum f_j \\theta_j}$',
        '$\\lambda_{soil}=k_{soil} / C_{soil}$']

    w.setColumnCount(len(headerLabels))
    w.setHorizontalHeaderLabels(headerLabels, 25)        
    w.setRowCount(3)
    w.setAlternatingRowColors(True)

    k = 1
    for j in range(3):
        for i in range(3):
            w.setItem(i, j, QtGui.QTableWidgetItem('Value %i' % (k)))
            k += 1

    w.show() 
    w.resize(700, 200)

    sys.exit(app.exec_())

其结果是:

解决方案并不完美,但这是一个很好的起点.我将在为自己的应用程序进行改进时对其进行更新.

The solution is not perfect, but it is a good starting point. I'll update it when I will improve it for my own application.

这篇关于在pyQt/pySide QTableWidget中显示LaTeX的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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