Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Search/Find functionality in QTableView

I have a QWidget and inside that, there is a QTableView. I need to have a find functionality on the first column of the table, so when I click on Ctrl+F, a find dialog will pop-up.

class Widget(QWidget):
    def __init__(self,md,parent=None):
        QWidget.__init__(self,parent)
        layout=QVBoxLayout(self)

        # initially construct the visible table
        tv = QTableView()
        # uncomment this if the last column shall cover the rest
        tv.horizontalHeader().setStretchLastSection(True)
        tv.show()

        # set black grid lines
        self.setStyleSheet("gridline-color: rgb(39, 42, 49)")

        # construct the Qt model belonging to the visible table
        model = NvmQtModel(md)
        tv.setModel(model)
        tv.resizeRowsToContents()
        tv.resizeColumnsToContents()

        # set the shortcut ctrl+F for find in menu
        shortcut = QShortcut(QKeySequence('Ctrl+f'), self)
        shortcut.activated.connect(self.handleFind)

        # delegate for decimal
        delegate = NvmDelegate()
        tv.setItemDelegate(delegate)
        self.setGeometry(200,200,600,600) # adjust this later
        layout.addWidget(tv)

        # set window title
        self.setWindowTitle("TITLE")

    # shows and handles the find dialog
    def handleFind(self):
        findDialog = QDialog()
        grid = QGridLayout()
        findDialog.setLayout(grid)

        findLabel = QLabel("Find what", findDialog)
        grid.addWidget(findLabel,1,0)
        findField = QLineEdit(findDialog)
        grid.addWidget(findField,1,1)
        findButton = QPushButton("Find", findDialog)
        findButton.clicked.connect(self.find)
        grid.addWidget(findButton,2,1)

        findDialog.exec_()

    # find function: search in the first column of the table   
    def find(self):
        #to do

    # prevent closing the window  without confirmation
    def closeEvent(self, event):
        reply=QMessageBox.question(self,'Message',"Are you sure to quit?",QMessageBox.Yes|QMessageBox.No,QMessageBox.No)
        if reply==QMessageBox.Yes:
            event.accept()
        else:
            event.ignore()

# create the application and the new tree view container
app=QApplication(sys.argv)
wid=Widget(md)
wid.show()
wid.raise_()

I have problem in the findButton action where it should search in the first column of the table. I would appreciate if you guide me in this issue.

like image 269
Orcl User Avatar asked Dec 19 '13 23:12

Orcl User


1 Answers

Firstly, you will need to change the way the findButton is connected, so that it sends the text to be searched for:

findButton.clicked.connect(
    lambda: self.find(findField.text()))

Then you can search in your table by using the match method of the tableview's model:

def find(self, text, column=0):
    model = self.table.model()
    start = model.index(0, column)
    matches = model.match(
        start, QtCore.Qt.DisplayRole,
        text, 1, QtCore.Qt.MatchContains)
    if matches:
        index = matches[0]
        # index.row(), index.column()
        self.table.selectionModel().select(
            index, QtGui.QItemSelectionModel.Select)

UPDATE:

The method above will find the first cell that contains the given text, and then select it. If you wanted to find the next cell that matches, start would need to be set to the appropriate index of the current selection (if there is one). This could be obtained with:

    indexes = self.table.selectionModel().selectedIndexes()
like image 161
ekhumoro Avatar answered Nov 20 '22 14:11

ekhumoro