Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Qt for Python
  4. PySide6 QTableView integration into GUI
Forum Updated to NodeBB v4.3 + New Features

PySide6 QTableView integration into GUI

Scheduled Pinned Locked Moved Solved Qt for Python
pysideqt for pythonpython
7 Posts 5 Posters 2.9k Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • C Offline
    C Offline
    ccortez
    wrote on last edited by
    #1

    So I am trying to integrate a table into my PySide6 GUI. My goal is to have the table display data from a pandas dataframe, and show it on the GUI to the user. This GUI would also include other elements in it, such as some buttons and other text.

    The problem I am currently running into is that when I add a table into my window, it takes up the whole screen. Here is an image of what I am describing:

    db_snippet.png

    I want it to look more like a small view of the table within the actual window, not taking up the whole window. There are other elements I want to be visible, and resizing the table to a smaller size doesn't really seem to do the trick.

    Is this something that isn't possible? I'd like to think that I am not the only person who has ever wanted to do this. I feel like I am maybe missing something small.

    Here is my code:

    import sys
    
    from PySide6 import QtCore
    from PySide6.QtCore import Qt
    from PySide6.QtWidgets import QApplication, QMainWindow, QLabel, QVBoxLayout, QTableView
    #from PySide6.QtSql import QSqlDatabase, QSqlDriver, QSqlQuery
    import pandas as pd
    from sqlalchemy import create_engine
    
    class TableModel(QtCore.QAbstractTableModel):
    
        def __init__(self, data):
            super(TableModel, self).__init__()
            self._data = data
    
        def data(self, index, role):
            if role == Qt.DisplayRole:
                value = self._data.iloc[index.row(), index.column()]
                return str(value)
    
        def rowCount(self, index):
            return self._data.shape[0]
    
        def columnCount(self, index):
            return self._data.shape[1]
    
        def headerData(self, section, orientation, role):
            # section is the index of the column/row.
            if role == Qt.DisplayRole:
                if orientation == Qt.Horizontal:
                    return str(self._data.columns[section])
    
                if orientation == Qt.Vertical:
                    return str(self._data.index[section])
    
    class DBEntry(QMainWindow):
        def __init__(self):
            super(DBEntry, self).__init__()
            # Adjusting dimensions of window and the title text size
            self.setWindowTitle('Database Entry')
            self.resize(640, 900)
            self.label = QLabel(self)
            self.label.setGeometry(120, 0, 400, 100)
            self.label.setText('Database')
            self.label.setAlignment(Qt.AlignCenter)
            self.label.setStyleSheet('font-size:40px')
            self.layout = QVBoxLayout()
            # Data created here and converted into DF
            engine = create_engine('postgresql://postgres:*******@localhost:5432/sampledb')
            df = pd.read_sql('formalloy', engine)
            #Table initiation with a call to TableModel class
            self.table = QTableView()
            self.model = TableModel(df)
            self.table.setModel(self.model)
            self.table.resize(200, 200)
            self.setCentralWidget(self.table)
    
    
    if __name__ == '__main__':
        app = QApplication(sys.argv)
        ex = DBEntry()
        ex.show()
        sys.exit(app.exec())
    
    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi,

      Your issue is that you are setting the QTableView as central widget.

      Use a "dummy" widget for the central widget and build your UI in it.

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      C 1 Reply Last reply
      2
      • SGaistS SGaist

        Hi,

        Your issue is that you are setting the QTableView as central widget.

        Use a "dummy" widget for the central widget and build your UI in it.

        C Offline
        C Offline
        ccortez
        wrote on last edited by
        #3

        @SGaist Hello, thank you for your response.
        Can you clarify what you mean by creating a dummy widget and building my UI into it?
        As far as your comment about the central widget, is there an alternative for showing the table inside of the GUI outside of central widget?

        JonBJ 1 Reply Last reply
        0
        • C ccortez

          @SGaist Hello, thank you for your response.
          Can you clarify what you mean by creating a dummy widget and building my UI into it?
          As far as your comment about the central widget, is there an alternative for showing the table inside of the GUI outside of central widget?

          JonBJ Offline
          JonBJ Offline
          JonB
          wrote on last edited by JonB
          #4

          @ccortez
          Look at the diagram in https://doc.qt.io/qt-5/qmainwindow.html#details. Set your central widget to a QWidget. Put a QLayout on that. Now sizing should be good. Add your QTableView onto the layout. Work from there. Should be better.

          1 Reply Last reply
          2
          • C Offline
            C Offline
            ccortez
            wrote on last edited by ccortez
            #5

            @JonB Okay I think I somewhat figured it out. That was helpful.
            Not sure if this is something you or @SGaist could help with but I am now running into this issue.
            Here is a picture:

            db_sc.png

            I got something a little better going now but there is still the issue of the table taking up more space than it should. As you can see there are only 4 rows but the table is taking up a lot more space than that. I added another dummy column of data to extend out the columns, and it seems to react somewhat responsively to this. I'd like to achieve this with that long blank area of nothing in the table.

            Using the .resize() doesn't do anything, so I am not really sure how to make it so that it isnt so long and taking up so much space.

            Code;

            import sys
            from PySide6.QtCore import Qt, QAbstractTableModel
            from PySide6.QtWidgets import QApplication, QMainWindow, QLabel, QVBoxLayout, QTableView, QWidget, QPushButton
            import pandas as pd
            from sqlalchemy import create_engine
            
            class pandasModel(QAbstractTableModel):
            
                def __init__(self, data):
                    QAbstractTableModel.__init__(self)
                    self._data = data
            
                def rowCount(self, parent=None):
                    return self._data.shape[0]
            
                def columnCount(self, parent=None):
                    return self._data.shape[1]
            
                def data(self, index, role=Qt.DisplayRole):
                    if index.isValid():
                        if role == Qt.DisplayRole:
                            return str(self._data.iloc[index.row(), index.column()])
                    return None
            
                def headerData(self, col, orientation, role):
                    if orientation == Qt.Horizontal and role == Qt.DisplayRole:
                        return self._data.columns[col]
                    return None
            
            class DBEntry(QMainWindow):
                def __init__(self):
                    super(DBEntry, self).__init__()
                    # Adjusting dimensions of window and the title text size
                    self.setWindowTitle('Database Entry')
                    self.resize(540, 480)
                    label = QLabel()
                    label.setGeometry(120, 0, 400, 100)
                    label.setText('Database')
                    label.setAlignment(Qt.AlignCenter)
                    label.setStyleSheet('font-size:40px')
            
                    engine = create_engine('postgresql://postgres:******@localhost:5432/sampledb')
                    df = pd.read_sql('formalloy', engine)
                    model = pandasModel(df)
                    table = QTableView()
                    table.setModel(model)
                    #table.resize(100, 100)
                    btn = QPushButton()
                    btn.resize(250, 250)
                    btn.setText('Database')
                    btn.setStyleSheet('font-size:15px')
            
                    self.layout = QVBoxLayout()
                    self.layout.addWidget(label)
                    self.layout.addWidget(table)
                    self.layout.addWidget(btn)
                    self.widget = QWidget()
                    self.widget.setLayout(self.layout)
                    self.setCentralWidget(self.widget)
            
            if __name__ == '__main__':
                app = QApplication(sys.argv)
                ex = DBEntry()
                ex.show()
                sys.exit(app.exec())
            
            Thank YouT jsulmJ 2 Replies Last reply
            0
            • C ccortez

              @JonB Okay I think I somewhat figured it out. That was helpful.
              Not sure if this is something you or @SGaist could help with but I am now running into this issue.
              Here is a picture:

              db_sc.png

              I got something a little better going now but there is still the issue of the table taking up more space than it should. As you can see there are only 4 rows but the table is taking up a lot more space than that. I added another dummy column of data to extend out the columns, and it seems to react somewhat responsively to this. I'd like to achieve this with that long blank area of nothing in the table.

              Using the .resize() doesn't do anything, so I am not really sure how to make it so that it isnt so long and taking up so much space.

              Code;

              import sys
              from PySide6.QtCore import Qt, QAbstractTableModel
              from PySide6.QtWidgets import QApplication, QMainWindow, QLabel, QVBoxLayout, QTableView, QWidget, QPushButton
              import pandas as pd
              from sqlalchemy import create_engine
              
              class pandasModel(QAbstractTableModel):
              
                  def __init__(self, data):
                      QAbstractTableModel.__init__(self)
                      self._data = data
              
                  def rowCount(self, parent=None):
                      return self._data.shape[0]
              
                  def columnCount(self, parent=None):
                      return self._data.shape[1]
              
                  def data(self, index, role=Qt.DisplayRole):
                      if index.isValid():
                          if role == Qt.DisplayRole:
                              return str(self._data.iloc[index.row(), index.column()])
                      return None
              
                  def headerData(self, col, orientation, role):
                      if orientation == Qt.Horizontal and role == Qt.DisplayRole:
                          return self._data.columns[col]
                      return None
              
              class DBEntry(QMainWindow):
                  def __init__(self):
                      super(DBEntry, self).__init__()
                      # Adjusting dimensions of window and the title text size
                      self.setWindowTitle('Database Entry')
                      self.resize(540, 480)
                      label = QLabel()
                      label.setGeometry(120, 0, 400, 100)
                      label.setText('Database')
                      label.setAlignment(Qt.AlignCenter)
                      label.setStyleSheet('font-size:40px')
              
                      engine = create_engine('postgresql://postgres:******@localhost:5432/sampledb')
                      df = pd.read_sql('formalloy', engine)
                      model = pandasModel(df)
                      table = QTableView()
                      table.setModel(model)
                      #table.resize(100, 100)
                      btn = QPushButton()
                      btn.resize(250, 250)
                      btn.setText('Database')
                      btn.setStyleSheet('font-size:15px')
              
                      self.layout = QVBoxLayout()
                      self.layout.addWidget(label)
                      self.layout.addWidget(table)
                      self.layout.addWidget(btn)
                      self.widget = QWidget()
                      self.widget.setLayout(self.layout)
                      self.setCentralWidget(self.widget)
              
              if __name__ == '__main__':
                  app = QApplication(sys.argv)
                  ex = DBEntry()
                  ex.show()
                  sys.exit(app.exec())
              
              Thank YouT Offline
              Thank YouT Offline
              Thank You
              wrote on last edited by Thank You
              #6

              @ccortez
              You can use spacer (QSpacerItem) for keeping unwanted space blank.
              or if you know exact row length you can set its height and width.

              Another way would be to calculate height for every resize according to total number of rows.

              Let's make QT free or It will go forever

              TRUE AND FALSE <3

              1 Reply Last reply
              0
              • C ccortez

                @JonB Okay I think I somewhat figured it out. That was helpful.
                Not sure if this is something you or @SGaist could help with but I am now running into this issue.
                Here is a picture:

                db_sc.png

                I got something a little better going now but there is still the issue of the table taking up more space than it should. As you can see there are only 4 rows but the table is taking up a lot more space than that. I added another dummy column of data to extend out the columns, and it seems to react somewhat responsively to this. I'd like to achieve this with that long blank area of nothing in the table.

                Using the .resize() doesn't do anything, so I am not really sure how to make it so that it isnt so long and taking up so much space.

                Code;

                import sys
                from PySide6.QtCore import Qt, QAbstractTableModel
                from PySide6.QtWidgets import QApplication, QMainWindow, QLabel, QVBoxLayout, QTableView, QWidget, QPushButton
                import pandas as pd
                from sqlalchemy import create_engine
                
                class pandasModel(QAbstractTableModel):
                
                    def __init__(self, data):
                        QAbstractTableModel.__init__(self)
                        self._data = data
                
                    def rowCount(self, parent=None):
                        return self._data.shape[0]
                
                    def columnCount(self, parent=None):
                        return self._data.shape[1]
                
                    def data(self, index, role=Qt.DisplayRole):
                        if index.isValid():
                            if role == Qt.DisplayRole:
                                return str(self._data.iloc[index.row(), index.column()])
                        return None
                
                    def headerData(self, col, orientation, role):
                        if orientation == Qt.Horizontal and role == Qt.DisplayRole:
                            return self._data.columns[col]
                        return None
                
                class DBEntry(QMainWindow):
                    def __init__(self):
                        super(DBEntry, self).__init__()
                        # Adjusting dimensions of window and the title text size
                        self.setWindowTitle('Database Entry')
                        self.resize(540, 480)
                        label = QLabel()
                        label.setGeometry(120, 0, 400, 100)
                        label.setText('Database')
                        label.setAlignment(Qt.AlignCenter)
                        label.setStyleSheet('font-size:40px')
                
                        engine = create_engine('postgresql://postgres:******@localhost:5432/sampledb')
                        df = pd.read_sql('formalloy', engine)
                        model = pandasModel(df)
                        table = QTableView()
                        table.setModel(model)
                        #table.resize(100, 100)
                        btn = QPushButton()
                        btn.resize(250, 250)
                        btn.setText('Database')
                        btn.setStyleSheet('font-size:15px')
                
                        self.layout = QVBoxLayout()
                        self.layout.addWidget(label)
                        self.layout.addWidget(table)
                        self.layout.addWidget(btn)
                        self.widget = QWidget()
                        self.widget.setLayout(self.layout)
                        self.setCentralWidget(self.widget)
                
                if __name__ == '__main__':
                    app = QApplication(sys.argv)
                    ex = DBEntry()
                    ex.show()
                    sys.exit(app.exec())
                
                jsulmJ Online
                jsulmJ Online
                jsulm
                Lifetime Qt Champion
                wrote on last edited by
                #7

                @ccortez said in PySide6 QTableView integration into GUI:

                Using the .resize() doesn't do anything

                Yes, because size of widgets in a layout is managed by the layout.
                What is the problem with table consuming all available space? If it would not then you would simply have unused space, it would not look better in my opinion.

                https://forum.qt.io/topic/113070/qt-code-of-conduct

                1 Reply Last reply
                1

                • Login

                • Login or register to search.
                • First post
                  Last post
                0
                • Categories
                • Recent
                • Tags
                • Popular
                • Users
                • Groups
                • Search
                • Get Qt Extensions
                • Unsolved