Search code examples
pythonscopepyqt5qt-designer

Get current value of another widget in a custom (promoted) widget in Qt Designer using PyQt5


I have created the ui for my application using Qt Designer. The UI includes two Widgets. A dropdown (ComboBox) with different values each representing a year (2015, 2025, 2035) and a custom widget that loads a shapefile on a map: Here is a screenshot of the UI ( Also, here is library.ui file) :

enter image description here

Here is my index.py file to connect to ui:

import sys

from os import environ
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *

from PyQt5.uic import loadUiType


ui,_=loadUiType('library.ui')

def suppress_qt_warnings():
    environ["QT_DEVICE_PIXEL_RATIO"] = "0"
    environ["QT_AUTO_SCREEN_SCALE_FACTOR"] = "1"
    environ["QT_SCREEN_SCALE_FACTORS"] = "1"
    environ["QT_SCALE_FACTOR"] = "1"


class MainApp(QMainWindow, ui):
    def __init__(self):
        QMainWindow.__init__(self)
        self.setupUi(self)

def main():
    suppress_qt_warnings()
    app=QApplication(sys.argv)
    window = MainApp()
    window.show()
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

and here is the file associated with my custom widget (leafwidget.py):

import folium
import os.path

from PyQt5 import QtCore, QtWebEngineWidgets
from PyQt5.QtWidgets  import *
import geopandas as gpd


CURRENT_DIR = os.path.dirname(os.path.realpath(__file__))

class LeafWidget (QWidget):
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)
        self.view = QtWebEngineWidgets.QWebEngineView()

        shp_filename = os.path.join(CURRENT_DIR, "input", '2015_loaded_NoCC.dbf')
        shp_file = gpd.read_file(shp_filename)
        shp_file_json_str = shp_file.to_json()

        m = folium.Map(location=[39.764075, -86.159019], zoom_start=10)
        folium.GeoJson(shp_file_json_str).add_to(m)

        tmp_file = QtCore.QTemporaryFile("net.html", self)
        if tmp_file.open():
            m.save(tmp_file.fileName())
            url = QtCore.QUrl.fromLocalFile(tmp_file.fileName())
            self.view.load(url)

        lay = QVBoxLayout(self)
        lay.addWidget(self.view)
        self.show()

As you can see in my custom widget Class (LeafWidget), the dbf file's name starts with the year value (2015, 2025, 2035) followed by "_loaded_NocCC.dbf" (for example "2015_loaded_NoCC.shp" and so on).

Now, I need to access the selected value from the dropdown list (let's say 2025) and then display the corresponding shapefile in the map (2025_loaded_NoCC.shp).

I can access the value of ComboBox easily using self.ComboBox.currentText() inside index.py, but in the leafletwidget class (leafwidget.py), I don't have access to self.ComboBox.currentText() and get the error that basically my Class has no attribute "ComboBox".

SO, how can I access the value of ComboBox in my LeafWidget class?


Solution

  • You have to create a method that updates the shapefile that will be shown, and call that method every time a new option is chosen generating the new path:

    import folium
    
    from PyQt5 import QtCore, QtWebEngineWidgets
    from PyQt5.QtWidgets import *
    import geopandas as gpd
    
    
    class LeafWidget(QWidget):
        def __init__(self, parent=None):
            QWidget.__init__(self, parent)
            self.view = QtWebEngineWidgets.QWebEngineView()
            lay = QVBoxLayout(self)
            lay.addWidget(self.view)
            self.tmp_file = QtCore.QTemporaryFile("XXXXXX.html")
    
        def set_shapefile(self, filename):
            shp_file = gpd.read_file(filename)
            shp_file_json_str = shp_file.to_json()
            m = folium.Map(location=[39.764075, -86.159019], zoom_start=10)
            folium.GeoJson(shp_file_json_str).add_to(m)
            if self.tmp_file.open():
                m.save(self.tmp_file.fileName())
                url = QtCore.QUrl.fromLocalFile(self.tmp_file.fileName())
                self.view.load(url)
    
    import sys
    import os.path
    
    from os import environ
    from PyQt5.QtCore import *
    from PyQt5.QtGui import *
    from PyQt5.QtWidgets import *
    
    from PyQt5.uic import loadUiType
    
    CURRENT_DIR = os.path.dirname(os.path.realpath(__file__))
    
    
    ui, _ = loadUiType(os.path.join(CURRENT_DIR, "library.ui"))
    
    
    def suppress_qt_warnings():
        environ["QT_DEVICE_PIXEL_RATIO"] = "0"
        environ["QT_AUTO_SCREEN_SCALE_FACTOR"] = "1"
        environ["QT_SCREEN_SCALE_FACTORS"] = "1"
        environ["QT_SCALE_FACTOR"] = "1"
    
    
    class MainApp(QMainWindow, ui):
        def __init__(self):
            QMainWindow.__init__(self)
            self.setupUi(self)
            self.comboBox.currentTextChanged.connect(self.handle_currentTextChanged)
            self.handle_currentTextChanged(self.comboBox.currentText())
    
        def handle_currentTextChanged(self, text):
            filename = shp_filename = os.path.join(
                CURRENT_DIR, "input", "{}_loaded_NoCC.shp".format(text)
            )
            self.LeafWidget.set_shapefile(filename)
    
    
    def main():
        suppress_qt_warnings()
        app = QApplication(sys.argv)
        window = MainApp()
        window.show()
        sys.exit(app.exec_())
    
    
    if __name__ == "__main__":
        main()