event driven coding PyQt6 on Combobox change - Printable Version +- Python Forum (https://python-forum.io) +-- Forum: Python Coding (https://python-forum.io/forum-7.html) +--- Forum: GUI (https://python-forum.io/forum-10.html) +--- Thread: event driven coding PyQt6 on Combobox change (/thread-39785.html) |
event driven coding PyQt6 on Combobox change - merrittr - Apr-14-2023 I have the working code below running in a venv using python 3.7.6 what I want is when the Province combobox is changed have the stations combobox updated with that selected Provinces stations. How do I hook that event? import sys from PyQt6 import QtGui, QtCore import bs4 from bs4 import BeautifulSoup import requests #import urllib3 as urllib # the lib that handles the url stuff import urllib.request provs = ['AB','BC','MB','NB','NL','NS','NT','NU','ON','PE','QC','SK','YT'] for prov in provs: print(prov) url = 'https://dd.weather.gc.ca/hydrometric/csv/' + prov + '/daily/' + prov + '_daily_hydrometric.csv' print(url) #https://dd.weather.gc.ca/hydrometric/doc/hydrometric_StationList.csv def getStationsProv(provis): data = urllib.request.urlopen('https://dd.weather.gc.ca/hydrometric/doc/hydrometric_StationList.csv') # it's a file like object and works just like a file dataFiltered = [] for line in data: # files are iterable #print(line.decode()) data = line.decode().split(",") # dataFiltered.append("Station1") if data[4] == provis : arrayData = str(data[0]) + '-' + str(data[1]).replace('"','').replace(' ','_') dataFiltered.append(arrayData) # print(arrayData) # print(dataFiltered) # dataFiltered.append("Station2") return dataFiltered import sys from PyQt6.QtCore import Qt from PyQt6.QtWidgets import ( QApplication, QCheckBox, QComboBox, QDateEdit, QDateTimeEdit, QDial, QDoubleSpinBox, QFontComboBox, QLabel, QLCDNumber, QLineEdit, QMainWindow, QProgressBar, QPushButton, QRadioButton, QSlider, QSpinBox, QTimeEdit, QVBoxLayout, QWidget, ) # Subclass QMainWindow to customize your application's main window class MainWindow(QMainWindow): def getValue(self): provIs = self.cbUser.itemData(self.qcb1.currentIndex()).toPyObject() print(str(id_us)) def __init__(self): super().__init__() self.setWindowTitle("Env Canada hydrometric data") self.setFixedWidth(500) layout = QVBoxLayout() label1 = QLabel("Select a province") #, layout.addWidget(label1) qcb1 = QComboBox() #, qcb1.addItems(provs) layout.addWidget(qcb1) qcb2 = QComboBox() df = getStationsProv(qcb1.currentText()) #df = getStationsProv('AB') #print(df) qcb2.addItems(df) layout.addWidget(qcb2) widget = QWidget() widget.setLayout(layout) self.setCentralWidget(widget) app = QApplication(sys.argv) window = MainWindow() window.show() app.exec() RE: event driven coding PyQt6 on Combobox change - Axel_Erfurt - Apr-14-2023 You can connect QComboBox.currentIndexChanged() to the function import sys from PyQt6.QtCore import Qt from PyQt6.QtWidgets import ( QApplication, QCheckBox, QComboBox, QDateEdit, QDateTimeEdit, QDial, QDoubleSpinBox, QFontComboBox, QLabel, QLCDNumber, QLineEdit, QMainWindow, QProgressBar, QPushButton, QRadioButton, QSlider, QSpinBox, QTimeEdit, QVBoxLayout, QWidget, ) import bs4 from bs4 import BeautifulSoup import requests #import urllib3 as urllib # the lib that handles the url stuff import urllib.request provs = ['AB','BC','MB','NB','NL','NS','NT','NU','ON','PE','QC','SK','YT'] for prov in provs: print(prov) url = 'https://dd.weather.gc.ca/hydrometric/csv/' + prov + '/daily/' + prov + '_daily_hydrometric.csv' print(url) #https://dd.weather.gc.ca/hydrometric/doc/hydrometric_StationList.csv def getStationsProv(provis): data = urllib.request.urlopen('https://dd.weather.gc.ca/hydrometric/doc/hydrometric_StationList.csv') # it's a file like object and works just like a file dataFiltered = [] for line in data: # files are iterable #print(line.decode()) data = line.decode().split(",") # dataFiltered.append("Station1") if data[4] == provis : arrayData = str(data[0]) + '-' + str(data[1]).replace('"','').replace(' ','_') dataFiltered.append(arrayData) # print(arrayData) # print(dataFiltered) # dataFiltered.append("Station2") return dataFiltered # Subclass QMainWindow to customize your application's main window class MainWindow(QMainWindow): def getValue(self): provIs = self.cbUser.itemData(self.qcb1.currentIndex()).toPyObject() print(str(id_us)) def __init__(self): super().__init__() self.setWindowTitle("Env Canada hydrometric data") self.setFixedWidth(500) layout = QVBoxLayout() label1 = QLabel("Select a province") #, layout.addWidget(label1) self.qcb1 = QComboBox() #, self.qcb1.addItems(provs) self.qcb1.currentIndexChanged.connect(self.qcb1_index_changed) layout.addWidget(self.qcb1) self.qcb2 = QComboBox() layout.addWidget(self.qcb2) widget = QWidget() widget.setLayout(layout) self.setCentralWidget(widget) self.qcb1_index_changed() def qcb1_index_changed(self): self.qcb2.clear() print("qcb1_index_changed") df = getStationsProv(self.qcb1.currentText()) self.qcb2.addItems(df) app = QApplication(sys.argv) window = MainWindow() window.show() app.exec() RE: event driven coding PyQt6 on Combobox change - deanhystad - Apr-14-2023 I would write like this: import sys from PyQt5 import QtWidgets import urllib.request provinces = ("AB", "BC", "MB", "NB", "NL", "NS", "NT", "NU", "ON", "PE", "QC", "SK", "YT") province_station_url = ( "https://dd.weather.gc.ca/hydrometric/doc/hydrometric_StationList.csv" ) class MainWindow(QtWidgets.QMainWindow): """Demonstrate QComboBox.currentIndexChanged.""" def __init__(self): super().__init__() self.setWindowTitle("Env Canada hydrometric data") center = QtWidgets.QWidget(self) self.setCentralWidget(center) layout = QtWidgets.QVBoxLayout(center) label = QtWidgets.QLabel("Select a province", center) layout.addWidget(label) self.province = QtWidgets.QComboBox(center) self.province.addItems(provinces) layout.addWidget(self.province) self.stations = QtWidgets.QComboBox(center) layout.addWidget(self.stations) # Update station list when province changes self.province.currentIndexChanged.connect(self.update_stations) self.update_stations() def update_stations(self): """Update station list based on selected province.""" self.stations.clear() province = self.province.currentText() for line in urllib.request.urlopen(province_station_url): info = line.decode().strip().split(",") # To prevent an index error, check length first if len(info) >= 5 and info[4] == province: self.stations.addItem(f"""{info[1].replace('"', '').replace(' ', '_')}""") app = QtWidgets.QApplication(sys.argv) window = MainWindow() window.show() app.exec()Notes: Generally, I prefer to import packages and use the package name to help identify where I am getting classes or functions. For Qt this means I prefer this: import sys from PyQt5 import QtWidgets ... app = QtWidgets.QApplication(sys.argv)to this: from sys import argv from PyQt5.QtWidgets import QApplication ... app = QApplication(argv)I don't know if this happens on other platforms, but on Windows I used to have a problem with widgets popping up as windows on the screen when the application started only to disappear before the main window was drawn. This does not happen when I specify the parent when I create a widget instead of waiting for the layout manager to do so. That is why you see this in my code: center = QtWidgets.QWidget(self) # make the center widget as a child of the MainWindow self.setCentralWidget(center) layout = QtWidgets.QVBoxLayout(center) label = QtWidgets.QLabel("Select a province", center) # When making widgets, specify the parentI do not know if this happens on other operating systems. RE: event driven coding PyQt6 on Combobox change - merrittr - May-03-2023 Hey That works perfectly Thanks Axel! |