mnekkach
mnekkach

Reputation: 343

PyQt5 POO Call instance of Class in another class

I would like when I click on a buttom from a toolbar created with PyQt get the selected items in a QListWidget created in other class (LisWorkDirectory class).

In the ToolBar.py in the compilation_ function, I would like to get all selected items. I want to get the instance of the ListWorkDirectory class to get the QListWidget that I created the first time I have launched my app.

If I instanciate ListWorkDirectory, I get a new instance, and the selectedItems return a empty list, it is a normal behaviour.

Maybe my architecture is not correct, so if you have any suggestion or remarks don't' hesitate to learn me.

Below my code so that you understand my request :

main.py

from MainWindow import MainWindow
from MenuBar import MenuBar
from ToolBar import ToolBar
from PyQt5.QtWidgets import QApplication
import sys

app = QApplication(sys.argv)

#Window
windowApp = MainWindow("pyCompile")
#MenuBar
menuBar = MenuBar()
#ToolBar
toolBar = ToolBar()

windowApp.setMenuBar(menuBar)
windowApp.addToolBar(toolBar)

windowApp.show()

sys.exit(app.exec_())

MainWindow.py

from PyQt5.QtWidgets import QMainWindow, QWidget, QLineEdit, QPushButton, QListWidget,QListWidgetItem,QPlainTextEdit, QFileDialog, QStatusBar ,QVBoxLayout, QHBoxLayout
from PyQt5.QtGui import QIcon
from PyQt5.QtCore import Qt
from ListWorkDirectory import ListWorkDirectory
from Logger import MyDialog
import logging
import os

class MainWindow(QMainWindow):
    def __init__(self, windowTitle):
        super().__init__()
        #Logger
        self.logger = MyDialog()
        logging.info("pyCompile version 0.1")

        self.setGeometry(150,250,600,350)
        self.setWindowTitle(windowTitle)
        
        self.workDirectoryField = QLineEdit()
        self.workDirectoryField.setPlaceholderText("Select your work directory ...")
        self.workDirectoryField.setText("F:/WORKSPACE/Projects")
        
        self.workDirectoryButton = QPushButton()
        self.workDirectoryButton.setIcon(QIcon(":folder.svg"))
        self.workDirectoryButton.clicked.connect(self.launchDialog)
        
        self.hBoxLayout = QHBoxLayout()
        self.hBoxLayout.addWidget(self.workDirectoryField)
        self.hBoxLayout.addWidget(self.workDirectoryButton)
        
        #List folder in work directory
        self.myListFolder = ListWorkDirectory()
        print(self.myListFolder)
        self.workDirectoryField.textChanged[str].connect(self.myListFolder.update)



        self.hBoxLayoutLogger = QHBoxLayout()
        self.hBoxLayoutLogger.addWidget(self.myListFolder)

        self.hBoxLayoutLogger2 = QHBoxLayout()
        self.hBoxLayoutLogger2.addWidget(self.logger)

        self.centralWidget = QWidget(self)
        self.setCentralWidget(self.centralWidget)
        
        self.vBoxLayout = QVBoxLayout(self.centralWidget)
        self.vBoxLayout.addLayout(self.hBoxLayout)
        self.vBoxLayout.addLayout(self.hBoxLayoutLogger)
        self.vBoxLayout.addLayout(self.hBoxLayoutLogger2)


        #Status Bar
        self.statusBar = QStatusBar()
        self.statusBar.showMessage("Welcome in pyCompile", 5000)
        self.setStatusBar(self.statusBar)

    
    def launchDialog(self):
        workDirectory = QFileDialog.getExistingDirectory(self, caption="Select work directory")
        print(workDirectory)
        self.workDirectoryField.setText(workDirectory)

MenuBar.py

from PyQt5.QtWidgets import QMenuBar

class MenuBar(QMenuBar):
    def __init__(self):
        super().__init__()
        self.fileMenu = "&File"
        self.editMenu = "&Edit"
        self.helpMenu = "&Help"
        self.initUI()
        
    def initUI(self):
        self.addMenu(self.fileMenu)
        self.addMenu(self.editMenu)
        self.addMenu(self.helpMenu)

ToolBar.py

from PyQt5.QtWidgets import QMainWindow, QToolBar, QAction
from PyQt5.QtGui import QIcon
import qrc_resources
from ListWorkDirectory import ListWorkDirectory

class ToolBar(QToolBar, ListWorkDirectory):
    def __init__(self):
        super().__init__()
        self._createActions()
        self.initUI()
    

    def initUI(self):

        self.setMovable(False)
        self.addAction(self.compileAction)
        self.addAction(self.settingsAction)
        self.addAction(self.quitAction)

    def _createActions(self):
        self.compileAction = QAction(self)
        self.compileAction.setStatusTip("Launch compilation")
        self.compileAction.setText("&Compile")
        self.compileAction.setIcon(QIcon(":compile.svg"))
        self.compileAction.triggered.connect(self.compilation_)


        self.settingsAction = QAction(self)
        self.settingsAction.setText("&Settings")
        self.settingsAction.setIcon(QIcon(":settings.svg"))
        


        self.quitAction = QAction(self)
        self.quitAction.setText("&Quit")
        self.quitAction.setIcon(QIcon(":quit.svg"))

    
    def compilation_(self):
        """
        Get the instance of ListWorkDirectory to get selected items and launch the 
        compilation
        """

ListWorkDirectory.py

from PyQt5.QtWidgets import QListWidget,QListWidgetItem
from PyQt5.QtCore import Qt, QDir
import os

class ListWorkDirectory(QListWidget):
    
    def __init__(self):
        super().__init__()
        self.clear()

    
    def update(self, workDirectoryField):
        
        isPathCorrect = self.checkPath(workDirectoryField)
        
        if(isPathCorrect):
            listOfDirectory = self.getFolderList(workDirectoryField, os.listdir(workDirectoryField))
            for folder in listOfDirectory:
                self.item = QListWidgetItem(folder)
                self.item.setCheckState(Qt.Unchecked)
                self.addItem(self.item)

        else:
            self.clear()

    

    def checkPath(self, path):
        QPath = QDir(path)
        isQPathExist = QPath.exists()
        isPathEmpty  = self.isPathEmpty(path)
        if(isQPathExist and not isPathEmpty):
            return True
        else:
            return False

    
    def getFolderList(self, path, listOfFiles):
        listOfFolders=[]
        for file_ in listOfFiles:
            if(os.path.isdir(os.path.join(path, file_))):
                listOfFolders.append(file_)
            else:
                pass
        return listOfFolders
    
    
    
    def isPathEmpty(self, path):

        if(path != ""):
            return False
        
        else:
            return True

Thank you for your help.

Upvotes: 0

Views: 416

Answers (1)

furas
furas

Reputation: 142899

When you add widget to window (or to other widget) then this window (or widget) is its parent and you can use self.parent() to access element in window (or widget). When widgets are nested then you may even use self.parent().parent()

def compilation_(self):
    """
    Get the instance of ListWorkDirectory to get selected items and launch the 
    compilation
    """

    print(self.parent().myListFolder)

EDIT:

Class ListWorkDirectory has function item(number) to get item from list - but you overwrite it with line self.item = QListWidgetItem(folder). If you remove self. and use

item = QListWidgetItem(folder)
item.setCheckState(Qt.Unchecked)
self.addItem(item)

then this will show only checked items

    def compilation_(self):
        """
        Get the instance of ListWorkDirectory to get selected items and launch the 
        compilation
        """
        lst = self.parent().myListFolder

        for x in range(lst.count()):
            item = lst.item(x)
            #print(item.checkState(), item.text())
            if item.checkState() :
                print(item.text())

Full working code - everyone can simply copy all to one file and run it.

from PyQt5.QtWidgets import QMainWindow, QWidget, QLineEdit, QPushButton, QListWidget,QListWidgetItem,QPlainTextEdit, QFileDialog, QStatusBar ,QVBoxLayout, QHBoxLayout
from PyQt5.QtGui import QIcon
from PyQt5.QtCore import Qt
import logging
import os

# ---

from PyQt5.QtWidgets import QMenuBar

class MenuBar(QMenuBar):
    def __init__(self):
        super().__init__()
        self.fileMenu = "&File"
        self.editMenu = "&Edit"
        self.helpMenu = "&Help"
        self.initUI()
        
    def initUI(self):
        self.addMenu(self.fileMenu)
        self.addMenu(self.editMenu)
        self.addMenu(self.helpMenu)

# ---

from PyQt5.QtWidgets import QMainWindow, QToolBar, QAction
from PyQt5.QtGui import QIcon

class ToolBar(QToolBar):
    def __init__(self):
        super().__init__()
        self._createActions()
        self.initUI()
    

    def initUI(self):

        self.setMovable(False)
        self.addAction(self.compileAction)
        self.addAction(self.settingsAction)
        self.addAction(self.quitAction)

    def _createActions(self):
        self.compileAction = QAction(self)
        self.compileAction.setStatusTip("Launch compilation")
        self.compileAction.setText("&Compile")
        self.compileAction.setIcon(QIcon(":compile.svg"))
        self.compileAction.triggered.connect(self.compilation_)


        self.settingsAction = QAction(self)
        self.settingsAction.setText("&Settings")
        self.settingsAction.setIcon(QIcon(":settings.svg"))
        


        self.quitAction = QAction(self)
        self.quitAction.setText("&Quit")
        self.quitAction.setIcon(QIcon(":quit.svg"))

    
    def compilation_(self):
        """
        Get the instance of ListWorkDirectory to get selected items and launch the 
        compilation
        """
        lst = self.parent().myListFolder

        for x in range(lst.count()):
            item = lst.item(x)
            #print(item.checkState(), item.text())
            if item.checkState() :
                print(item.text())

# ---

from PyQt5.QtWidgets import QListWidget, QListWidgetItem
from PyQt5.QtCore import Qt, QDir
import os

class ListWorkDirectory(QListWidget):
    
    def __init__(self):
        super().__init__()
        self.clear()

    
    def update(self, workDirectoryField):
        
        isPathCorrect = self.checkPath(workDirectoryField)
        
        if(isPathCorrect):
            listOfDirectory = self.getFolderList(workDirectoryField, os.listdir(workDirectoryField))
            for folder in listOfDirectory:
                item = QListWidgetItem(folder)
                item.setCheckState(Qt.Unchecked)
                self.addItem(item)

        else:
            self.clear()

    

    def checkPath(self, path):
        QPath = QDir(path)
        isQPathExist = QPath.exists()
        isPathEmpty  = self.isPathEmpty(path)
        if(isQPathExist and not isPathEmpty):
            return True
        else:
            return False

    
    def getFolderList(self, path, listOfFiles):
        listOfFolders=[]
        for file_ in listOfFiles:
            if(os.path.isdir(os.path.join(path, file_))):
                listOfFolders.append(file_)
            else:
                pass
        return listOfFolders
    
    
    
    def isPathEmpty(self, path):

        if(path != ""):
            return False
        
        else:
            return True


class MainWindow(QMainWindow):
    def __init__(self, windowTitle):
        super().__init__()
        #Logger
        #self.logger = MyDialog()
        logging.info("pyCompile version 0.1")

        self.setGeometry(150,250,600,350)
        self.setWindowTitle(windowTitle)
        
        self.workDirectoryField = QLineEdit()
        self.workDirectoryField.setPlaceholderText("Select your work directory ...")
        self.workDirectoryField.setText("F:/WORKSPACE/Projects")
        
        self.workDirectoryButton = QPushButton()
        self.workDirectoryButton.setIcon(QIcon(":folder.svg"))
        self.workDirectoryButton.clicked.connect(self.launchDialog)
        
        self.hBoxLayout = QHBoxLayout()
        self.hBoxLayout.addWidget(self.workDirectoryField)
        self.hBoxLayout.addWidget(self.workDirectoryButton)
        
        #List folder in work directory
        self.myListFolder = ListWorkDirectory()
        print(self.myListFolder)
        self.workDirectoryField.textChanged[str].connect(self.myListFolder.update)

        self.hBoxLayoutLogger = QHBoxLayout()
        self.hBoxLayoutLogger.addWidget(self.myListFolder)

        self.hBoxLayoutLogger2 = QHBoxLayout()
        #self.hBoxLayoutLogger2.addWidget(self.logger)

        self.centralWidget = QWidget(self)
        self.setCentralWidget(self.centralWidget)
        
        self.vBoxLayout = QVBoxLayout(self.centralWidget)
        self.vBoxLayout.addLayout(self.hBoxLayout)
        self.vBoxLayout.addLayout(self.hBoxLayoutLogger)
        self.vBoxLayout.addLayout(self.hBoxLayoutLogger2)


        #Status Bar
        self.statusBar = QStatusBar()
        self.statusBar.showMessage("Welcome in pyCompile", 5000)
        self.setStatusBar(self.statusBar)

    
    def launchDialog(self):
        workDirectory = QFileDialog.getExistingDirectory(self, caption="Select work directory")
        print(workDirectory)
        self.workDirectoryField.setText(workDirectory)
        
# ---

from PyQt5.QtWidgets import QApplication
import sys

app = QApplication(sys.argv)

#Window
windowApp = MainWindow("pyCompile")
#MenuBar
menuBar = MenuBar()
#ToolBar
toolBar = ToolBar()

windowApp.setMenuBar(menuBar)
windowApp.addToolBar(toolBar)

windowApp.show()

sys.exit(app.exec_())

Upvotes: 1

Related Questions