Search code examples
pythonpyqt5qtableviewqradiobutton

How can I add QRadioButton Widget to QTableView in pyqt5


I am creating a tool that that will have a search option. After searching I am creating a dataframe and displaying it in QTableView. 1- I need to show a radio button against each row in table view. Radio button will be the first column in Table view. I have found table view method setIndexWidget() but not sure how to implement it.

2- I have 3 columns in tableview MemberNumber,FirstName,LastName once I will select radio button against my 1st row and click on show Data Button it should show member number in msg box.

Below is the code which I have written till now-

import sys
import pandas as pd
from PyQt5 import QtCore, QtGui
from PyQt5.QtCore import QAbstractTableModel, Qt
from PyQt5.QtWidgets import (QWidget, QLabel, QPushButton, QGridLayout, QDesktopWidget, 
                             QApplication, QTableView,QGroupBox,QLineEdit,QRadioButton,QModelIndex)
 
class Radio_button(QWidget):
  
    def __init__(self):
        super().__init__()
        
        self.initUI()

    def initUI(self):
        # set window title
        self.setWindowTitle('Search Window')
        self.show()  
#        self.setFixedSize(650, 450)
        
        window_layout = QGridLayout()
        rect = QtCore.QRect(10, 10, 300, 200)
        window_layout.setGeometry(rect)
        self.setLayout(window_layout)
        
        # Radio button for male
        self.radioButton_male = QRadioButton('R1')
        
        self.table=QTableView()
        window_layout.addWidget(self.table)       
        
 
        # adding signal and slot
        self.radioButton_male.toggled.connect(lambda: self.maleselected('Male'))
        
        # Radio button for female
        self.radioButton_female = QRadioButton('R2')
         
        # adding signal and slot
        self.radioButton_female.toggled.connect(lambda: self.maleselected('Female'))
        
        # Add label
        self.label = QLabel()
        
        # Add button
        self.show_data=QPushButton('Show Data',clicked = lambda : self.showData())
                
        window_layout.addWidget(self.label,3,0)
        window_layout.addWidget(self.radioButton_male,1,0)
        window_layout.addWidget(self.radioButton_female,2,0)
        window_layout.addWidget(self.table,0,0)
        window_layout.addWidget(self.show_data,4,0)
        self.radioButton=QRadioButton()
        self.index=0
        self.table.setIndexWidget(QModelIndex,self.radioButton)

     
    def maleselected(self, gender):
            self.label.setText("You are "+gender)
            
    def createdf(self):
        data = {'Name':['Tom', 'nick', 'krish', 'jack'],
        'Age':[20, 21, 19, 18]}
        df=pd.DataFrame(data)
        return df
    
    def showData(self):
        
        model = pandasModel(self.createdf())
        self.table.setModel(model)
        
                

     
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, parnet=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  
             
def main():
    app = QApplication(sys.argv)
    mc = Radio_button()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()

Solution

  • Please find the answer below-

    import pandas as pd
    from PyQt5 import QtCore, QtGui
    from PyQt5.QtCore import QAbstractTableModel, Qt
    from PyQt5.QtWidgets import (QWidget, QLabel, QPushButton, QGridLayout, QDesktopWidget, 
                                 QApplication, QTableView,QGroupBox,QLineEdit,QRadioButton,QButtonGroup)
     
    class Radio_button(QWidget):
      
        def __init__(self):
            super().__init__()
            
            self.initUI()
    
        def initUI(self):
            # set window title
            self.setWindowTitle('Search Window')
            self.show()  
    #        self.setFixedSize(650, 450)
            
            window_layout = QGridLayout()
            rect = QtCore.QRect(10, 10, 300, 200)
            window_layout.setGeometry(rect)
            self.setLayout(window_layout)
            
            # Radio button for male
            self.radioButton_male = QRadioButton('R1')
            
            self.table=QTableView()
            window_layout.addWidget(self.table)       
            
     
            # adding signal and slot
            self.radioButton_male.toggled.connect(lambda: self.maleselected('Male'))
            
            # Radio button for female
            self.radioButton_female = QRadioButton('R2')
             
            # adding signal and slot
            self.radioButton_female.toggled.connect(lambda: self.maleselected('Female'))
            
            # Add label
            self.label = QLabel()
            
            # Add button
            self.show_data=QPushButton('Show Data',clicked = lambda : self.showData())
            
            self.showRadio_data=QPushButton('Show Radio Data',clicked = lambda : self.showRadioData())
            
             
           # Add Widgets to layout 
            window_layout.addWidget(self.label,3,0)
            window_layout.addWidget(self.radioButton_male,1,0)
            window_layout.addWidget(self.radioButton_female,2,0)
            window_layout.addWidget(self.table,0,0)
            window_layout.addWidget(self.show_data,4,0)
            window_layout.addWidget(self.showRadio_data,5,0)
            
            
            
        def showRadioData(self,value):
    #        self.label.setText(self.radioButton.text())
            self.label.setText(str(value))
            
            
    
         
        def maleselected(self, gender):
                self.label.setText("You are "+gender)
                
        def createdf(self):
            data = {'Select':['','','',''],
                    'Employee ID':[12,13,14,15],
                    'Name':['Tom', 'nick', 'krish', 'jack'],
                    'Age':[20, 21, 19, 18]}
            df=pd.DataFrame(data)
            return df
        
        def showData(self):
            data=self.createdf()
            model = pandasModel(data)
            self.table.setModel(model)
            for idx, value in enumerate(data['Employee ID'].unique()):
                self.radioButton =QRadioButton(str(value))
                self.radioButton.toggled.connect(lambda toggled, _value=value: self.showRadioData(_value)) 
                self.table.setIndexWidget(self.table.model().index(idx, 0), self.radioButton)
                 
    
         
    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, parnet=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  
                 
    def main():
        app = QApplication(sys.argv)
        mc = Radio_button()
        sys.exit(app.exec_())
    
    if __name__ == '__main__':
        main()
    

    thank you @musicamate