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. QTableVIew

QTableVIew

Scheduled Pinned Locked Moved Solved Qt for Python
4 Posts 2 Posters 1.3k Views
  • 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.
  • W Offline
    W Offline
    worldsnexthero
    wrote on last edited by worldsnexthero
    #1

    Hi, if a user presses a button on my PyQt5 GUI, it runs a python script which dumps data into a .csv file and then I use pandas to create dataframe out of the .csv. Finally, the dataframe is displayed using QTableView in a new window without any problem.

    However, there is an additional checkbox option in my GUI. If checked, the python script will continuously run and overwrite the .csv file, meaning 5 different datasets. I want GUI to update the QTableView for every overwrite. For each overwrite, all data is overwritten (meaning all rows of data in dataframe)

    For debugging, rather than continuous run, I have altered the checkbox option code so that python script is ran only 5 times. Couple of issues I'm seeing:

    1. While the python script is running 5 times, the window with displayed table is not accessible until all 5 script runs are finished.
    2. Upon each python script run, the QTableVIew is not updated. I can verify because once the QTableView is accessible after 5th run, it is not matching the 5th output.

    Ideally I want only the data to update if checkbox option is clicked.

    Here is my code (kind of minimized/variables changed for privacy purposes):

    
    from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout
    from PyQt5.QtGui import QIcon
    
    from PyQt5 import QtWidgets, QtCore, uic, QtGui
    from PyQt5.QtWidgets import QMessageBox
    
    class TableModel(QtCore.QAbstractTableModel):
    
        def __init__(self, data, parent=None):
            QtCore.QAbstractTableModel.__init__(self, parent)
            self._data = data
    
        def rowCount(self, parent=None):
            return len(self._data.index)
        
        def columnCount(self, parent=None):
            return self._data.columns.size
    
        def data(self, index, role=QtCore.Qt.DisplayRole):
            if index.isValid():
                if role == QtCore.Qt.DisplayRole:
                    return str(self._data.iloc[index.row(), index.column()])
            return None    
    
    
        def headerData(self, rowcol, orientation, role):
            if orientation == QtCore.Qt.Horizontal and role == QtCore.Qt.DisplayRole:
                return self._data.columns[rowcol]
            if orientation == QtCore.Qt.Vertical and role == QtCore.Qt.DisplayRole:
                return self._data.index[rowcol]
            return None
    
        def flags(self, index):
            flags = super(self.__class__, self).flags(index)
            flags |= QtCore.Qt.ItemIsEditable
            flags |= QtCore.Qt.ItemIsSelectable
            flags |= QtCore.Qt.ItemIsEnabled
            flags |= QtCore.Qt.ItemIsDragEnabled
            flags |= QtCore.Qt.ItemIsDropEnabled
            return flags
    
        def sort(self, Ncol, order):
            """Sort table by given column number.
            """
            try:
                self.layoutAboutToBeChanged.emit()
                self._data = self._data.sort_values(self._data.columns[Ncol], ascending=not order)
                self.layoutChanged.emit()
            except Exception as e:
                print(e)
    
    class App(QtWidgets.QMainWindow):
        def __init__(self):
            super(App, self).__init__()
            uic.loadUi('Example.ui', self)
    
            self.button.clicked.connect(self.run_script)
            self.checkboxbutton.stateChanged.connect(self.run_script_5times) 
    
        def run_script(self):
    
            self.script_cmd = 'python3.7 example.py > example_data.csv'
            os.system(self.script_cmd)
            df = pd.read_csv('example_data.csv', index_col=False)
            self.model = TableModel(df)
            self.table = QtWidgets.QTableView()
            self.table.setModel(self.model)
            self.table.show()
    
      def run_script_5times(self, state):
            i = 0
            while state == QtCore.Qt.Checked and i < 5:
                time.sleep(3)
                os.system(self.script_cmd)
     
                df2 = pd.read_csv('example_data.csv', index_col=False)
                self.model.data=df2
                self.model.layoutChanged.emit()
                i = i + 1
    ``
    

    End goal is to have a table update with each python run without the table reloading, only the data. RIght now table is not updating and secondly once it does, I have seen examples where refresh is choppy - would like to avoid that. Let me know if I can help clarify - if someone knows options I can try?

    JonBJ 1 Reply Last reply
    0
    • W worldsnexthero

      Awesome, this does fix (1) qtableview window inaccessible. this is solved.

      After removing time.sleep() from the code, the existing code from original comment does not update qtableview, that problem still exists. Have looked at numerous sources online and have not seen much help regarding qtableview being overwritten with new data (same table format) from another pandas dataframe. Any thoughts on this front?

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

      @worldsnexthero

      Upon each python script run, the QTableVIew is not updated. I can verify because once the QTableView is accessible after 5th run, it is not matching the 5th output.

      and secondly once it does, I have seen examples where refresh is choppy - would like to avoid that

      Not sure what exactly you mean by either of these, or how they are connected.

              self.model = TableModel(df)
              self.table = QtWidgets.QTableView()
              self.table.setModel(self.model)
      

      Not sure how your QTableView is shown since it's not parented by QMainWindow nor addWidget() -ed anywhere. You sure you're loading into the table you see?. Maybe it's right to recreate the model & view each time, but when you talk about "choppy" I would be thinking about having one constant view, and perhaps one constant model which gets reloaded from the script.

      Test your code without any of the Python scrip[t/csv stuff, and if any funnies also don't do any sorting and see if that is relevant.

      1 Reply Last reply
      0
      • W worldsnexthero

        Hi, if a user presses a button on my PyQt5 GUI, it runs a python script which dumps data into a .csv file and then I use pandas to create dataframe out of the .csv. Finally, the dataframe is displayed using QTableView in a new window without any problem.

        However, there is an additional checkbox option in my GUI. If checked, the python script will continuously run and overwrite the .csv file, meaning 5 different datasets. I want GUI to update the QTableView for every overwrite. For each overwrite, all data is overwritten (meaning all rows of data in dataframe)

        For debugging, rather than continuous run, I have altered the checkbox option code so that python script is ran only 5 times. Couple of issues I'm seeing:

        1. While the python script is running 5 times, the window with displayed table is not accessible until all 5 script runs are finished.
        2. Upon each python script run, the QTableVIew is not updated. I can verify because once the QTableView is accessible after 5th run, it is not matching the 5th output.

        Ideally I want only the data to update if checkbox option is clicked.

        Here is my code (kind of minimized/variables changed for privacy purposes):

        
        from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout
        from PyQt5.QtGui import QIcon
        
        from PyQt5 import QtWidgets, QtCore, uic, QtGui
        from PyQt5.QtWidgets import QMessageBox
        
        class TableModel(QtCore.QAbstractTableModel):
        
            def __init__(self, data, parent=None):
                QtCore.QAbstractTableModel.__init__(self, parent)
                self._data = data
        
            def rowCount(self, parent=None):
                return len(self._data.index)
            
            def columnCount(self, parent=None):
                return self._data.columns.size
        
            def data(self, index, role=QtCore.Qt.DisplayRole):
                if index.isValid():
                    if role == QtCore.Qt.DisplayRole:
                        return str(self._data.iloc[index.row(), index.column()])
                return None    
        
        
            def headerData(self, rowcol, orientation, role):
                if orientation == QtCore.Qt.Horizontal and role == QtCore.Qt.DisplayRole:
                    return self._data.columns[rowcol]
                if orientation == QtCore.Qt.Vertical and role == QtCore.Qt.DisplayRole:
                    return self._data.index[rowcol]
                return None
        
            def flags(self, index):
                flags = super(self.__class__, self).flags(index)
                flags |= QtCore.Qt.ItemIsEditable
                flags |= QtCore.Qt.ItemIsSelectable
                flags |= QtCore.Qt.ItemIsEnabled
                flags |= QtCore.Qt.ItemIsDragEnabled
                flags |= QtCore.Qt.ItemIsDropEnabled
                return flags
        
            def sort(self, Ncol, order):
                """Sort table by given column number.
                """
                try:
                    self.layoutAboutToBeChanged.emit()
                    self._data = self._data.sort_values(self._data.columns[Ncol], ascending=not order)
                    self.layoutChanged.emit()
                except Exception as e:
                    print(e)
        
        class App(QtWidgets.QMainWindow):
            def __init__(self):
                super(App, self).__init__()
                uic.loadUi('Example.ui', self)
        
                self.button.clicked.connect(self.run_script)
                self.checkboxbutton.stateChanged.connect(self.run_script_5times) 
        
            def run_script(self):
        
                self.script_cmd = 'python3.7 example.py > example_data.csv'
                os.system(self.script_cmd)
                df = pd.read_csv('example_data.csv', index_col=False)
                self.model = TableModel(df)
                self.table = QtWidgets.QTableView()
                self.table.setModel(self.model)
                self.table.show()
        
          def run_script_5times(self, state):
                i = 0
                while state == QtCore.Qt.Checked and i < 5:
                    time.sleep(3)
                    os.system(self.script_cmd)
         
                    df2 = pd.read_csv('example_data.csv', index_col=False)
                    self.model.data=df2
                    self.model.layoutChanged.emit()
                    i = i + 1
        ``
        

        End goal is to have a table update with each python run without the table reloading, only the data. RIght now table is not updating and secondly once it does, I have seen examples where refresh is choppy - would like to avoid that. Let me know if I can help clarify - if someone knows options I can try?

        JonBJ Online
        JonBJ Online
        JonB
        wrote on last edited by JonB
        #2

        @worldsnexthero said in QTableVIew:

        displayed table is not accessible until all 5 script runs are finished.

        Don't, and never, use time.sleep(), it blocks the event loop/updates. And your loop re-reads the file without allowing update even if you didn't have the sleep() there. Use a QTimer. Start with that, see whether that affects your second comment too.

        1 Reply Last reply
        2
        • W Offline
          W Offline
          worldsnexthero
          wrote on last edited by
          #3

          Awesome, this does fix (1) qtableview window inaccessible. this is solved.

          After removing time.sleep() from the code, the existing code from original comment does not update qtableview, that problem still exists. Have looked at numerous sources online and have not seen much help regarding qtableview being overwritten with new data (same table format) from another pandas dataframe. Any thoughts on this front?

          JonBJ 1 Reply Last reply
          0
          • W worldsnexthero

            Awesome, this does fix (1) qtableview window inaccessible. this is solved.

            After removing time.sleep() from the code, the existing code from original comment does not update qtableview, that problem still exists. Have looked at numerous sources online and have not seen much help regarding qtableview being overwritten with new data (same table format) from another pandas dataframe. Any thoughts on this front?

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

            @worldsnexthero

            Upon each python script run, the QTableVIew is not updated. I can verify because once the QTableView is accessible after 5th run, it is not matching the 5th output.

            and secondly once it does, I have seen examples where refresh is choppy - would like to avoid that

            Not sure what exactly you mean by either of these, or how they are connected.

                    self.model = TableModel(df)
                    self.table = QtWidgets.QTableView()
                    self.table.setModel(self.model)
            

            Not sure how your QTableView is shown since it's not parented by QMainWindow nor addWidget() -ed anywhere. You sure you're loading into the table you see?. Maybe it's right to recreate the model & view each time, but when you talk about "choppy" I would be thinking about having one constant view, and perhaps one constant model which gets reloaded from the script.

            Test your code without any of the Python scrip[t/csv stuff, and if any funnies also don't do any sorting and see if that is relevant.

            1 Reply Last reply
            0

            • Login

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