Associate an event double click on a QTableWidget to a slot and get the row

1

I am trying to double-click on the row of a table to call the method and know which row it is. I tried to do:

def Tabla(self):
    #Boton de exportar a excel
    toolButton = QtWidgets.QToolButton()
    icon1 = QtGui.QIcon()
    icon1.addPixmap(QtGui.QPixmap(os.getcwd()+"\images\excel_tras.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)

    toolButton.setIcon(icon1)
    toolButton.setObjectName("toolButton")
    #toolButton.clicked.connect(lambda i: exportar(self))

    #Tabla
    table = QtWidgets.QTableView()
    table.setObjectName("table")

    tableWidget = QtWidgets.QTableWidget()
    tableWidget.setObjectName("tableWidget")
    tableWidget.setColumnCount(len(self.columnas))
    tableWidget.setRowCount(len(self.listaDatos))
    tableWidget.setSortingEnabled(True)
    #Definir los eventos de la tabla
    tableWidget.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
    tableWidget.setSelectionMode(QtWidgets.QAbstractItemView.SingleSelection)
    tableWidget.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)

    #Evento
    tableWidget.doubleClicked.connect(lambda i: on_click(i, self)) 

    #Colocamos la cabecera
    tableWidget.setHorizontalHeaderLabels(self.columnas)
    header_view = tableWidget.horizontalHeader()
    header_view.setSectionResizeMode(QtWidgets.QHeaderView.ResizeToContents)

    #Layout
    self.mainLayout.addWidget(tableWidget, 7, 0, 5, 7)
    self.mainLayout.addWidget(toolButton, 6, 5, 1, 1, QtCore.Qt.AlignRight)

    return tableWidget

#Metodo asociado al evento de hacer doble click sobre una fila de la tabla    
def on_click(i, self):
    print(self.sender())#widget
    print(i)#qmodelindex

But I am not able to get the index of the row that I have selected.

By adding the slot the code would remain as:

from PyQt5 import QtCore
from PyQt5 import QtWidgets
from PyQt5 import QtGui
import configparser
import os
from util.excelUtil import *


class Tabla(QWidget):
'''
Metodo base para la creación de una tabla con el botón de exportación a excel
'''
def __init__(self, contenidoTabla):
        #Boton de exportar a excel
        self.toolButton = QtWidgets.QToolButton()
        icon1 = QtGui.QIcon()
        icon1.addPixmap(QtGui.QPixmap(os.getcwd()+"\images\excel_tras.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)

        self.toolButton.setIcon(icon1)
        self.toolButton.setObjectName("toolButton")
        self.toolButton.clicked.connect(lambda i: exportar(contenidoTabla))

        #Tabla
        contenidoTabla.table = QtWidgets.QTableView()
        contenidoTabla.table.setObjectName("table")

        contenidoTabla.tableWidget = QtWidgets.QTableWidget()
        contenidoTabla.tableWidget.setObjectName("tableWidget")
        contenidoTabla.tableWidget.setColumnCount(len(contenidoTabla.columnas))
        contenidoTabla.tableWidget.setRowCount(len(contenidoTabla.listaDatos))
        contenidoTabla.tableWidget.setSortingEnabled(True)
        #Definir los eventos de la tabla
        contenidoTabla.tableWidget.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
        contenidoTabla.tableWidget.setSelectionMode(QtWidgets.QAbstractItemView.SingleSelection)
        contenidoTabla.tableWidget.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)

        #Evento
        contenidoTabla.tableWidget.doubleClicked.connect(self.on_click)

        #Colocamos la cabecera
        contenidoTabla.tableWidget.setHorizontalHeaderLabels(contenidoTabla.columnas)
        header_view = contenidoTabla.tableWidget.horizontalHeader()
        header_view.setSectionResizeMode(QtWidgets.QHeaderView.ResizeToContents)

        #Layout
        contenidoTabla.mainLayout.addWidget(contenidoTabla.tableWidget, 7, 0, 5, 7)
        contenidoTabla.mainLayout.addWidget(self.toolButton, 6, 5, 1, 1, QtCore.Qt.AlignRight)

#Metodo asociado al evento de hacer doble click sobre una fila de la tabla    
@QtCore.pyqtSlot(QtWidgets.QTableWidgetItem)
def on_click(self, item):
    print(item.text())
    
asked by Adriana_0_0 23.08.2018 в 11:16
source

1 answer

1

The doubleClick signal already returns an instance QModelIndex from which you can obtain without problems the index of the row with QModelIndex.row() , the problem is that the signature of your slots and its call are incorrect in principle. An instance method must always receive self as the first argument , in addition self is passed automatically , you should not pass it explicitly when calling.

On the other hand, when calling a defined method def metodo(self, arg1) you must do it using self.metodo(arg1) , not using metodo(self, arg1) (in any case it would be NombreDeLaClase.metodo(self, arg1) which is what self.metodo(arg1) actually does)

Connect the signal with:

tableWidget.doubleClicked.connect(self.on_click) 

Your slot may look like this:

# from PyQt5 import QtCore

@QtCore.pyqtSlot(QtCore.QModelIndex)
def on_click(self, index):
    row = index.row()
    column = index.column()
    print(row, column)

With the button happens the same, do not use lambda to try to pass the instance of the class, simply:

toolButton.clicked.connect(self.exportar)

As long as exportar and on_click are of course instance methods of the same class that is the Tabla method. I leave a reproducible example based on your code anyway:

import sys
from PyQt5 import QtCore, QtWidgets 



class Example(QtWidgets.QDialog):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.mainLayout = QtWidgets.QGridLayout()
        self.setLayout(self.mainLayout)
        self.columnas = ["Columna 1", "Columna 2"]
        self.listaDatos = [["A", "B"],["C", "D"]]  
        self.tabla()        


    def tabla(self):
        #Boton de exportar a excel
        self.toolButton = QtWidgets.QToolButton()
        self.toolButton.clicked.connect(self.exportar)   # <<<<<<<<<<<<<<<<<<<<<<<
        #Tabla
        self.table = QtWidgets.QTableView()
        self.table.setObjectName("table")

        self.tableWidget = QtWidgets.QTableWidget()
        self.tableWidget.setObjectName("tableWidget")
        self.tableWidget.setColumnCount(len(self.columnas))
        self.tableWidget.setRowCount(len(self.listaDatos))

        #Colocamos la cabecera
        self.tableWidget.setHorizontalHeaderLabels(self.columnas)
        header_view = self.tableWidget.horizontalHeader()
        idx = header_view.count() - 1
        header_view.setSectionResizeMode(idx, QtWidgets.QHeaderView.ResizeToContents)

        #Colocamos los datos
        for fila, lista in enumerate(self.listaDatos):
            for columna, elemento in enumerate(lista):
                self.tableWidget.setItem(fila, columna,
                                         QtWidgets.QTableWidgetItem(elemento)
                                         )
        # Evento
        self.tableWidget.doubleClicked.connect(self.on_click)  # <<<<<<<<<<<<<<

        #Layout
        self.mainLayout.addWidget(self.tableWidget, 7, 0, 5, 7)
        self.mainLayout.addWidget(self.toolButton, 6, 5, 1, 1, QtCore.Qt.AlignRight)


    #Metodo asociado al evento de hacer doble click sobre una fila de la tabla 
    @QtCore.pyqtSlot(QtCore.QModelIndex)
    def on_click(self, index):
        row = index.row()
        column = index.column()
        print(row, column)


    @QtCore.pyqtSlot()
    def exportar(self):
        '''
        A modo de ejemplo solo imprime el contenido de la tabla
        en forma de csv
        '''
        print("Exportando tabla:")
        for row in range(self.tableWidget.rowCount()):
            print(",".join(self.tableWidget.item(row, column).text()
                for column in range(self.tableWidget.columnCount())))


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    dialog = Example()
    dialog.exec_()

Depending on what you want to finally get there are a couple of other signals that could help you:

For headers you also have similar signals, such as sectionDoubleClicked(logicalIndex: int) to get the index the row if you double click on a section of the vertical header:

self.tableWidget.verticalHeader().sectionDoubleClicked.connect(self.on_hheader_click)

@QtCore.pyqtSlot(int)
def on_hheader_click(self, index):
    print(index)
    
answered by 23.08.2018 / 12:14
source