【问题标题】:Displaying LaTeX in pyQt/pySide QTableWidget在 pyQt/pySide QTableWidget 中显示 LaTeX
【发布时间】:2015-11-09 04:43:08
【问题描述】:

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

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

setHorizo​​ntalHeaderLabels 只接受字符串。 我想知道是否有可能以某种方式实现这种 matplotlib 方法: matplotlib - write TeX on Qt form

还有其他选择吗?

【问题讨论】:

    标签: python qt pyqt latex pyside


    【解决方案1】:

    我也一直在尝试在 QTableWidget 的标题中显示复杂的标签。我可以通过重新实现 QHeaderViewpaintSection 方法并使用 thread on Qt Centre 中描述的 QTextDocument 手动绘制标签来做到这一点.

    但是,与 LaTex 相比,此解决方案有些局限。我认为尝试您在 OP 中建议的方法可能是一个好主意,即使用 matplotlib 的功能在 PySide 中呈现 LaTex。

    1。将 matplotlib Figure 转换为 QPixmap

    此方法需要的第一件事是能够将 matplotlib 图形转换为可以轻松绘制在任何 QWidget 上的格式。下面是一个将mathTex expression 作为输入并通过matplotlib 将其转换为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。将 QPixmap 绘制到 QTableWidget 的标题

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

    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。应用

    以下是上述的简单应用示例。

    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_())
    

    导致:

    解决方案并不完美,但它是一个很好的起点。当我为自己的应用程序改进它时,我会更新它。

    【讨论】:

    • @jankos 另一个选项(来自this post)是在表格标题中放置一个QWebEngineView,并使用MathJax 显示方程式。
    猜你喜欢
    • 1970-01-01
    • 2011-06-02
    • 1970-01-01
    • 2019-02-09
    • 2014-08-08
    • 2017-04-08
    • 1970-01-01
    • 2022-11-24
    • 1970-01-01
    相关资源
    最近更新 更多