使用 PyQt5 在 Qt Designer 中的自定义(升级)小部件中获取另一个小部件的当前值

Posted

技术标签:

【中文标题】使用 PyQt5 在 Qt Designer 中的自定义(升级)小部件中获取另一个小部件的当前值【英文标题】:Get current value of another widget in a custom (promoted) widget in Qt Designer using PyQt5 【发布时间】:2020-10-23 18:13:26 【问题描述】:

我已经使用 Qt Designer 为我的应用程序创建了 ui。 UI 包括两个小部件。具有不同值的下拉列表 (ComboBox),每个值代表一年 (2015, 2025, 2035) 和在地图上加载 shapefile 的自定义小部件:这是 UI 的屏幕截图 ( 另外,here 是 library.ui 文件):

这是我的 index.py 文件以连接到 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()

这是与我的自定义小部件关联的文件 (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()

正如您在我的自定义小部件类 (LeafWidget) 中看到的,dbf 文件的名称以年份值(2015、2025、2035)开头,后跟“_loaded_NocCC.dbf”(例如“2015_loaded_NoCC.shp”等)。

现在,我需要从下拉列表中访问选定的值(比如说 2025),然后在地图中显示相应的 shapefile (2025_loaded_NoCC.shp) .

我可以在 index.py 中使用 self.ComboBox.currentText() 轻松访问 ComboBox 的值,但在 Leafletwidget 类 (leafwidget.py) 中,我无权访问 self.ComboBox.currentText() 并得到基本上我的类没有属性“ComboBox”的错误。

那么,如何在 LeafWidget 类中访问 ComboBox 的值?

【问题讨论】:

请提供minimal reproducible example 刚刚做了.. 感谢您的注意! 分享 library.ui 在第一段中添加了指向它的链接.. 【参考方案1】:

您必须创建一个方法来更新将显示的 shapefile,并在每次选择新选项时调用该方法来生成新路径:

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()

【讨论】:

太棒了!非常感谢。

以上是关于使用 PyQt5 在 Qt Designer 中的自定义(升级)小部件中获取另一个小部件的当前值的主要内容,如果未能解决你的问题,请参考以下文章

Qt Designer PyQt5 覆盖 CloseEvent 子窗口不起作用

Qt Designer 和 PyQt5 自定义插件加载 TypeError

PyQt5配合Qt-Designer实现GUI

PyQt5 keyPressEvent 不适用于终止 App Qt Designer

使用 Qt Designer 表单和 PyQt5 在 QWidget 中绘制 matplotlib 图形

PyQt5 图形界面 - Qt Designer设置简体中文方法演示,Qt Designer字体设置,Qt Designer工具单独安装包获取,Qt Designer简体中文语言包获取