Penguin
Penguin

Reputation: 103

PyQt 5 QTableWidget.cellClicked Signal Not Working

I am trying to make a simple files app (or, file explorer app) and I am using the QTableWidget to Display the files and directories. When the user clicks an directory, I want the program to jump to that directory. I have used the QTableWidget.cellClicked signal, and it does not currently work.

The signal part:

self.filesTable.connect(print)#self.updateUiCellClick)

Added print instead of self.updateUiCellClick for debugging purposes.

Code (probably you do not need this): #!/usr/bin/python3

print('i Import Modules')
print(' | Import sys')
import sys
print(' | Import PyQt5.QtCore')
from PyQt5.QtCore import *
print(' | Import PyQt5.QtGui')
from PyQt5.QtGui import *
print(' | Import PyQt5.QtWidgets')
from PyQt5.QtWidgets import * # PyQt5 Support
print(' | Import os')
import os
print(' | Import subprocess.Popen') # For backward-compatibility
from subprocess import Popen, PIPE
print(' | Done')
print('i Define class Form')

class root(QMainWindow):

    def __init__(self, parent=None):
        '''self.__init__ - Initializes QMainWindow'''
        print('  self.__init__ - Initializes QMainWindow')
        super(root, self).__init__(parent)

        # Create Variables
        self.currentPath = '/'
        os.chdir(self.currentPath)
        self.currentItems = os.listdir()
        self.currentItemsLsProcess = Popen(['ls','-l'], stdout=PIPE, stderr=PIPE)
        self.currentItemsLsProcessResult = self.currentItemsLsProcess.communicate()
        if self.currentItemsLsProcessResult[1].decode('utf-8'):
            QMessageBox.warning(self,'Files - ls -l Error','ls -l responded with non-blank stderr.Error is shown here:<br><code>{}</code><br><hr><br>Error LsStderr (e-lsstderr)<br><hr><br>If you want to support the team, go to the <a href="https://github.com/">GitHub Repository</a>.'.format(self.currentItemsLsProcessResult[1].decode('utf-8')))
        self.currentItemsLs = self.currentItemsLsProcessResult[0].decode('utf-8').split('\n')[1:-1]

        # Create Table Widget
        self.filesTable = QTableWidget()

        # Init Table Widget
        self.filesTable.clear()
        self.filesTable.setSizeAdjustPolicy(QAbstractScrollArea.AdjustToContents)
        self.filesTable.setRowCount(len(self.currentItems))
        self.filesTable.setColumnCount(4)
        self.filesTable.setHorizontalHeaderLabels(['Name','TimeStamp','Type','ls -l'])
        # self.filesTable.setReadOnly(1)

        # Create & Add Items
        self.itemWidgets = [[],[],[],[]]
        for i in range(len(self.currentItems)):
            self.itemWidgets[0].append(QTableWidgetItem(self.currentItems[i]))
            self.filesTable.setItem(i,0,self.itemWidgets[0][-1])
            self.itemWidgets[3].append(QTableWidgetItem(self.currentItemsLs[i]))
            self.filesTable.setItem(i,3,self.itemWidgets[3][-1])

        # Init Widgets

        # Align Widgets to root
        self.setCentralWidget(self.filesTable)

        # Signals-and-Slots

        print('i Set self title')
        self.setWindowTitle('{}'.format(self.currentPath))

    def updateUi(self):
        '''self.updateUi - None'''
        os.chdir(self.currentPath)
        self.currentItems = os.listdir()
        self.currentItemsLsProcess = Popen(['ls','-l'], stdout=PIPE, stderr=PIPE)
        self.currentItemsLsProcessResult = self.currentItemsLsProcess.communicate()
        if self.currentItemsLsProcessResult[1].decode('utf-8'):
            QMessageBox.warning(self,'Files - ls -l Error','ls -l responded with non-blank stderr.Error is shown here:<br><code>{}</code><br><hr><br>Error LsStderr (e-lsstderr)<br><hr><br>If you want to support the team, go to the <a href="https://github.com/">GitHub Repository</a>.'.format(self.currentItemsLsProcessResult[1].decode('utf-8')))
        self.currentItemsLs = self.currentItemsLsProcessResult[0].decode('utf-8').split('\n')[1:-1]
        self.filesTable.clear()
        self.filesTable.setSizeAdjustPolicy(QtWidgets.QAbstractScrollArea.AdjustToContents)
        self.filesTable.setRowCount(len(self.currentItems))
        self.filesTable.setColumnCount(4)
        self.filesTable.setHorizontalHeaderLabels(['Name','TimeStamp','Type','ls -l'])
        self.itemWidgets = [[],[],[],[]]
        for i in range(len(self.currentItems)):
            self.itemWidgets[0].append(QTableWidgetItem(self.currentItems[i]))
            self.filesTable.setItem(i,0,self.itemWidgets[0][-1])
            self.filesTable..connect(print)#self.updateUiCellClick)
            self.itemWidgets[3].append(QTableWidgetItem(self.currentItemsLs[i]))
            self.filesTable.setItem(i,3,self.itemWidgets[3][-1])
        self.filesTable.resizeColumnsToContents()
        self.setWindowTitle('{}'.format(self.currentPath))

    def updateUiCellClick(self, row, column):
        '''self.updateUiCellClick - None'''
        print('self.updateUiCellClick - None')
        self.currentpath += self.itemWidgets[0][row].text+'/'
        self.updateUi()

print(' | Done')

if __name__ == '__main__':
    print('i Execute instance')
    app = QApplication(sys.argv)
    root = root()
    root.show()
    app.exec_()
    print(' | Done')

Upvotes: 1

Views: 4886

Answers (1)

eyllanesc
eyllanesc

Reputation: 243887

The connection should be as follows

self.filesTable.cellClicked.connect(self.updateUiCellClick)
                ^^^^^^^^^^^
                   signal

In addition to this it is not necessary to create the connection every time you fill in the table, it is enough when you create it.

If you look at code you see that many parts are repeating, which is not necessary, I take the boldness to make improvements to your code as the verification of path and reduce the code.

import sys

import os
from subprocess import Popen, PIPE
from PyQt5.QtWidgets import *


class Root(QMainWindow):
    def __init__(self, parent=None):
        print('  self.__init__ - Initializes QMainWindow')
        QMainWindow.__init__(self, parent)
        # Create Table Widget
        self.filesTable = QTableWidget()
        self.filesTable.cellClicked.connect(self.updateUiCellClick)

        # Init Table Widget
        self.filesTable.clear()
        self.filesTable.setSizeAdjustPolicy(QTableWidget.AdjustToContents)
        self.filesTable.setColumnCount(4)
        self.filesTable.setHorizontalHeaderLabels(['Name', 'TimeStamp', 'Type', 'ls -l'])
        # Init Widgets

        self.setCentralWidget(self.filesTable)
        self.populate_table("/")

    def populate_table(self, path):
        # Verify that it is a directory.
        if not os.path.isdir(path):
            return

        os.chdir(path)
        current_items = os.listdir()
        currentItemsLsProcess = Popen(['ls', '-l'], stdout=PIPE, stderr=PIPE)

        currentItemsLsProcessResult = currentItemsLsProcess.communicate()
        if currentItemsLsProcessResult[1].decode('utf-8'):
            QMessageBox.warning(self, 'Files - ls -l Error',
                                'ls -l responded with non-blank stderr.Error is shown here:'
                                '<br><code>{}</code><br><hr><br>Error LsStderr (e-lsstderr)<br>'
                                '<hr><br>If you want to support the team, go to the '
                                '<a href="https://github.com/">GitHub Repository</a>.'.format(
                                    currentItemsLsProcessResult[1].decode('utf-8')))
            return

        self.filesTable.clear()
        currentItemsLs = currentItemsLsProcessResult[0].decode('utf-8').split('\n')[1:-1]
        self.filesTable.setRowCount(len(current_items))

        for i, values in enumerate(zip(current_items, currentItemsLs)):
            name, ls = values
            self.filesTable.setItem(i, 0, QTableWidgetItem(name))
            self.filesTable.setItem(i, 3, QTableWidgetItem(ls))

        self.setWindowTitle('{}'.format(path))

    def updateUiCellClick(self, row, _):
        path = os.path.join(os.getcwd(), self.filesTable.item(row, 0).text())
        self.populate_table(path)


if __name__ == '__main__':
    print('i Execute instance')
    app = QApplication(sys.argv)
    root = Root()
    root.show()
    status = app.exec_()
    print(' | Done')
    sys.exit(status)

Upvotes: 2

Related Questions