如何在MainWindow类中访问PandasModel类的filtered_df DataFrame
解决MainWindow访问PandasModel中filtered_df的问题
问题根源
你在MainWindow的__init__方法里创建的model是局部变量,没有保存为MainWindow的实例属性,导致其他方法无法访问到这个PandasModel实例;另外filtered_df是PandasModel的实例属性,必须通过该实例才能访问。
修复步骤
将PandasModel实例保存为MainWindow的属性
在MainWindow的__init__中,把model = PandasModel(self.df)改为self.model = PandasModel(self.df),同时更新所有用到model的信号连接部分,替换为self.model。在display_filtered_map中访问filtered_df
直接通过self.model.filtered_df就能获取过滤后的DataFrame,还可以复用现有的display_map逻辑来展示过滤后的点位。
修改后的关键代码片段
MainWindow的__init__部分:
def __init__(self): super().__init__() self.setupUi(self) # run on startup self.setup() self.load_database() self.model = PandasModel(self.df) # 保存为实例属性 self.tv_RP.setModel(self.model) self.initialise() # signals self.pb_Close.clicked.connect(self.close) # 更新信号连接,使用self.model self.le_SearchCountry.textChanged.connect(lambda text: self.model.filter_data(text, self.le_SearchName.text(), self.le_SearchIdent.text(), self.le_SearchAirport.text())) self.le_SearchName.textChanged.connect(lambda text: self.model.filter_data(self.le_SearchCountry.text(), text, self.le_SearchIdent.text(), self.le_SearchAirport.text())) self.le_SearchIdent.textChanged.connect(lambda text: self.model.filter_data(self.le_SearchCountry.text(), self.le_SearchName.text(), text, self.le_SearchAirport.text())) self.le_SearchAirport.textChanged.connect(lambda text: self.model.filter_data(self.le_SearchCountry.text(), self.le_SearchName.text(), self.le_SearchIdent.text(), text)) self.pb_ResetSearches.clicked.connect(self.reset_searches) self.tv_RP.clicked.connect(self.get_row_data)
修改display_map方法以支持自定义DataFrame:
def display_map(self, location, df=None): # delete current webview self.webView.deleteLater() # 使用传入的df,没有则用原始self.df df_map = df.copy() if df is not None else self.df.copy() df_map['Popup'] = "Country: " + df_map['Country'] + "<br>" + \ "Name: " + df_map['Name'] + "<br>" + \ "Ident: " + df_map['Ident'] + "<br>" + \ "Elevation: " + df_map['Elevation'] + " feet" + "<br>" + \ "Position DD: " + df_map['Lat_DD'] + ", " + df_map['Lon_DD'] + "<br>" + \ "Position DMS: " + df_map['Lat_DMS'] + ", " + df_map['Lon_DMS'] # change columns to float df_map['Lat_DD'] = df_map['Lat_DD'].astype(float) df_map['Lon_DD'] = df_map['Lon_DD'].astype(float) # set up icons and markers vrp_map = folium.Map(location=location, zoom_start=12, control_scale=True) vrp_map.add_child(GetLatLngPopup()) callback = ('function (row) {' 'var marker = L.marker(new L.LatLng(row[0], row[1]), {color: "red"});' 'var icon = L.AwesomeMarkers.icon({icon: "info-sign", iconColor: "white", markerColor: "blue", prefix: "glyphicon", extraClasses: "fa-rotate-0"});' 'marker.setIcon(icon);' "var popup = L.popup({maxWidth: '300'});" "const display_text = {text: row[2]};" "var my_text = $(`<div id='my_text' class='display_text' style='width: 100.0%; height: 100.0%;'> " "${display_text.text}</div>`)[0];" "popup.setContent(my_text);" "marker.bindPopup(popup);" 'return marker};') vrp_map.add_child(FastMarkerCluster(df_map[['Lat_DD', 'Lon_DD', 'Popup']].values.tolist(), callback=callback)) # display map self.webView = QWebEngineView() self.webView.setHtml(vrp_map.get_root().render()) self.vl_Map.addWidget(self.webView) # destroy map dataframe del df_map
修改后的display_filtered_map方法:
def display_filtered_map(self): filtered_df = self.model.filtered_df if filtered_df.empty: print("没有过滤结果") return # 取第一个点位作为地图中心,或者根据需求调整 center_location = (float(filtered_df.iloc[0]['Lat_DD']), float(filtered_df.iloc[0]['Lon_DD'])) self.display_map(center_location, filtered_df)
额外说明
- 现在你可以通过调用
self.display_filtered_map()来展示过滤后的地图,比如可以给某个按钮添加点击信号连接到这个方法。 - 注意处理filtered_df为空的情况,避免报错。
内容的提问来源于stack exchange,提问作者passman
相关产品推荐
相关产品推荐

