0

The following code creates a table using QTableWidget and then It creates two PyQtGraphs, I need to place the table inside the second graph so that the borders of the table coincide with the borders of the graph (the rows are fixed while the columns are not, but for semplicity lets use a table with also fixed columns). The numbers inside the table are not important (they will be based on a calculation on the data of the first graph). How can I achieve this result?

from pyqtgraph.Qt import QtGui, QtCore
import pyqtgraph as pg
from PyQt6.QtWidgets import QTableWidget,QTableWidgetItem,QVBoxLayout
import sys

app = QtGui.QApplication([])
view = pg.GraphicsView()
l = pg.GraphicsLayout()
view.setCentralItem(l)
view.show()
view.resize(800,600)

p0 = l.addPlot(0, 0)
p0.showGrid(x = True, y = True, alpha = 1.0)

#have no x-axis tickmark below the upper plot (coordinate 0,0)
#without these lines, there will be separate coordinate systems with a gap inbetween
ax0 = p0.getAxis('bottom')      #get handle to x-axis 0
ax0.setStyle(showValues=False)  #this will remove the tick labels and reduces gap b/w plots almost to zero
                                #there will be a double line separating the plot rows


p1 = l.addPlot(1, 0)
p1.showGrid(x = True, y = True, alpha = 1.0)

p1.setXLink(p0)

p1.setMouseEnabled(y=False, x=False)

l.layout.setSpacing(0.)
l.setContentsMargins(0., 0., 0., 0.)

#Table
data = {'col1':['1','2','3','4'],
        'col2':['1','2','1','3'],
        'col3':['1','1','2','1']}


class TableView(QTableWidget):
    def __init__(self, data, *args):
        QTableWidget.__init__(self, *args)
        self.data = data
        self.setData()
        self.resizeColumnsToContents()
        self.resizeRowsToContents()

    def setData(self):
        horHeaders = []
        for n, key in enumerate(sorted(self.data.keys())):
            horHeaders.append(key)
            for m, item in enumerate(self.data[key]):
                newitem = QTableWidgetItem(item)
                self.setItem(m, n, newitem)
        self.setHorizontalHeaderLabels(horHeaders)

table = TableView(data, 4, 3)
table.show()

if __name__ == '__main__':
    if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
        QtGui.QApplication.instance().exec()

1 Answers1

0

I am not 100% sure I understand what you are trying to get with your code however, if you want to place a TableWidget below your Plot you could just use a QVBoxLayout then add your plot and table. You will have to pass your data to the plot and the table separately. Pyqtgraph also has a tablewidget that you can pass dictionaries and lists to so that you do not have to create a qt5 table widget from scratch.

Here is how I would write the program with using a main window widget class:

import sys

from PyQt5.QtWidgets import (QVBoxLayout, QMainWindow, QWidget, QApplication)
import pyqtgraph as pg

class plotAndTableWidget(QMainWindow):
    def __init__(self):
        super().__init__()
        self.initUI()
        self.create_data()

    def initUI(self):
        self.central_widget = QWidget()
        self.vertical_layout = QVBoxLayout()
        self.setCentralWidget(self.central_widget)
        self.central_widget.setLayout(self.vertical_layout)
        self.plot = pg.PlotWidget()
        self.table = pg.TableWidget()
        
        #The 1 after the plot and table essentially tells Qt to expand
        #those widgets evenly so they should take up a similar amount of space.
        self.vertical_layout.addWidget(self.plot, 1)
        self.vertical_layout.addWidget(self.table, 1)

    def create_data(self):
        data = {'col1':[1, 2, 3, 4],
                'col2':[1, 2, 1, 3],
                'col3':[1, 1 ,2, 1]}
        self.table.setData(data)
        
        for i in data.keys():
            self.plot.plot(y=data[i])

def run_program():
    app = QApplication(sys.argv)
    window = plotAndTableWidget()
    window.show()
    app.exec()
    #If you want to close your python interpreter you will need to add
    #sys.exit(app.exec_()) instead of app.exec().

if __name__ == '__main__':
    run_program()
lhnelson
  • 71
  • 2