如何在 Python 插件中使用多个 windows
How to use multiple windows in Python Plugin
我在 PyQGIS 中写了一个插件,其中包含几个 Ui(使用 QT Designer)。当我 运行 QGIS Python 控制台中的代码时,它运行得非常好。现在我想让它作为 classic QGIS 插件在公司内部使用(从菜单栏开始)。它总是与以前的插件配合得很好,但总是只有一个 Ui.
它的核心是三个重要的文件。 1.__init__.py,2.geowerkzeug.py,负责从菜单启动,3.functionality.py,里面包含了我所有的功能
##__init__.py
from Plugin.geowerkzeug import GeoWerkzeug
def classFactory(iface):
plugin = GeoWerkzeug(iface)
return plugin
现在 geowerkzeug.py:
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from plugin.functionality import *
from qgis.utils import iface
import os
class GeoWerkzeug:
def __init__ (self, iface):
self.iface = iface
def initGui (self):
self.startButton = QAction("Plugin starten", self.iface.mainWindow())
self.iface.addPluginToMenu('Plugin', self.startButton)
self.startButton.triggered.connect(self.maskeAufrufen)
def unload (self):
self.iface.removePluginMenu('Plugin', self.startButton)
def maskeAufrufen (self):
self.gui = MainWindow(self)
dock_widget = QDockWidget("Plugin", self.iface.mainWindow())
dock_widget.setWidget(self.gui)
self.iface.addDockWidget(QtCore.Qt.RightDockWidgetArea, dock_widget)
dock_widget.setAllowedAreas(QtCore.Qt.RightDockWidgetArea)
self.gui.show()
到这里它有效。 MainWindow 是 functionality.py 上的第一个 class。 window 将出现。但是如果我点击一个按钮切换到下一个 Ui (class),Ui 不会改变。我的插件中总共有 17 个 Ui。这里我只举两个class为例。
现在 functionality.py:
from PyQt5.uic import loadUi
from PyQt5 import QtWidgets
from PyQt5.QtWidgets import *
from PyQt5 import *
from qgis.core import *
from qgis.utils import iface
from qgis.gui import *
import processing
from PyQt5 import uic
import os
pluginPath = os.path.dirname(__file__)
uiPath = os.path.join(pluginPath, 'mainwindow.ui')
uiPath_second_window = os.path.join(pluginPath, 'window2.ui')
WIDGET, BASE = uic.loadUiType(uiPath)
widget = QDockWidget()
class MainWindow(BASE, WIDGET):
def __init__(self, parent=None):
super(MainWindow, self).__init__()
self.gui = loadUi(uiPath, self)
self.window_second.clicked.connect(self.next_window)
def next_window(self):
window_the_second=Second_window()
widget.setWidget(window_the_second)
class Second_window(BASE, WIDGET):
def __init__(self):
super(Second_window, self).__init__()
self.gui = loadUi(uiPath_second_window , self)
我最大的理解问题是如何正确地link 我的来自 functionality.py 的代码(控制台中的 运行s)与其他两个文件。下一个问题是我什至没有收到可以作为基础的错误消息。该插件在菜单栏中,可以启动,但之后我无法继续。我希望我的解释是可以理解的。
导致第二个 window 没有出现的主要问题是您从不显示 QDockWidget
。使用 widget.setWidget(window_the_second)
设置内容,但不会显示 window。
在显示第一个 window 的方法中,添加带有 self.iface.addDockWidget(QtCore.Qt.RightDockWidgetArea, widget)
的 dockwidget
然后将您的第一个 window 设置为该 dockwidget (widget.setWidget(self.gui)
) 的内容。
总的来说,你把一些事情弄混了,所以我会试着澄清两点。
- window 的内容是通过子类化
uic.loadUiType
的结果来设置的。为了让第二个 window 显示你的第二个 ui,你不能继承相同的 BASE
和 WIDGET
。改为为每个 UI 文件调用 uic.loadUiType
。
- 您缺少对
setupUi()
的调用以初始化 UI。然后你也可以摆脱任何 loadUi
.
实施我的建议会产生以下结果:
WIDGET, BASE = uic.loadUiType('1.ui')
WIDGET2, BASE2 = uic.loadUiType('2.ui')
widget = QDockWidget()
class GeoWerkzeug:
def __init__ (self, iface):
self.iface = iface
def initGui (self):
self.startButton = QAction("Plugin starten", self.iface.mainWindow())
self.iface.addPluginToMenu('Plugin', self.startButton)
self.startButton.triggered.connect(self.maskeAufrufen)
def unload (self):
self.iface.removePluginMenu('Plugin', self.startButton)
def maskeAufrufen (self):
# add DockWidget to GUI
self.iface.addDockWidget(QtCore.Qt.RightDockWidgetArea, widget)
widget.setAllowedAreas(QtCore.Qt.RightDockWidgetArea)
# set first window as content of the DockWidget
self.gui = MainWindow(self)
widget.setWidget(self.gui)
class MainWindow(BASE, WIDGET):
def __init__(self, parent=None):
super(MainWindow, self).__init__()
self.setupUi(self)
self.window_second.clicked.connect(self.next_window)
def next_window(self):
# set second window as content of the DockWidget
window_the_second=Second_window()
widget.setWidget(window_the_second)
class Second_window(BASE2, WIDGET2):
def __init__(self):
super(Second_window, self).__init__()
self.setupUi(self)
我在 PyQGIS 中写了一个插件,其中包含几个 Ui(使用 QT Designer)。当我 运行 QGIS Python 控制台中的代码时,它运行得非常好。现在我想让它作为 classic QGIS 插件在公司内部使用(从菜单栏开始)。它总是与以前的插件配合得很好,但总是只有一个 Ui.
它的核心是三个重要的文件。 1.__init__.py,2.geowerkzeug.py,负责从菜单启动,3.functionality.py,里面包含了我所有的功能
##__init__.py
from Plugin.geowerkzeug import GeoWerkzeug
def classFactory(iface):
plugin = GeoWerkzeug(iface)
return plugin
现在 geowerkzeug.py:
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from plugin.functionality import *
from qgis.utils import iface
import os
class GeoWerkzeug:
def __init__ (self, iface):
self.iface = iface
def initGui (self):
self.startButton = QAction("Plugin starten", self.iface.mainWindow())
self.iface.addPluginToMenu('Plugin', self.startButton)
self.startButton.triggered.connect(self.maskeAufrufen)
def unload (self):
self.iface.removePluginMenu('Plugin', self.startButton)
def maskeAufrufen (self):
self.gui = MainWindow(self)
dock_widget = QDockWidget("Plugin", self.iface.mainWindow())
dock_widget.setWidget(self.gui)
self.iface.addDockWidget(QtCore.Qt.RightDockWidgetArea, dock_widget)
dock_widget.setAllowedAreas(QtCore.Qt.RightDockWidgetArea)
self.gui.show()
到这里它有效。 MainWindow 是 functionality.py 上的第一个 class。 window 将出现。但是如果我点击一个按钮切换到下一个 Ui (class),Ui 不会改变。我的插件中总共有 17 个 Ui。这里我只举两个class为例。
现在 functionality.py:
from PyQt5.uic import loadUi
from PyQt5 import QtWidgets
from PyQt5.QtWidgets import *
from PyQt5 import *
from qgis.core import *
from qgis.utils import iface
from qgis.gui import *
import processing
from PyQt5 import uic
import os
pluginPath = os.path.dirname(__file__)
uiPath = os.path.join(pluginPath, 'mainwindow.ui')
uiPath_second_window = os.path.join(pluginPath, 'window2.ui')
WIDGET, BASE = uic.loadUiType(uiPath)
widget = QDockWidget()
class MainWindow(BASE, WIDGET):
def __init__(self, parent=None):
super(MainWindow, self).__init__()
self.gui = loadUi(uiPath, self)
self.window_second.clicked.connect(self.next_window)
def next_window(self):
window_the_second=Second_window()
widget.setWidget(window_the_second)
class Second_window(BASE, WIDGET):
def __init__(self):
super(Second_window, self).__init__()
self.gui = loadUi(uiPath_second_window , self)
我最大的理解问题是如何正确地link 我的来自 functionality.py 的代码(控制台中的 运行s)与其他两个文件。下一个问题是我什至没有收到可以作为基础的错误消息。该插件在菜单栏中,可以启动,但之后我无法继续。我希望我的解释是可以理解的。
导致第二个 window 没有出现的主要问题是您从不显示 QDockWidget
。使用 widget.setWidget(window_the_second)
设置内容,但不会显示 window。
在显示第一个 window 的方法中,添加带有 self.iface.addDockWidget(QtCore.Qt.RightDockWidgetArea, widget)
然后将您的第一个 window 设置为该 dockwidget (widget.setWidget(self.gui)
) 的内容。
总的来说,你把一些事情弄混了,所以我会试着澄清两点。
- window 的内容是通过子类化
uic.loadUiType
的结果来设置的。为了让第二个 window 显示你的第二个 ui,你不能继承相同的BASE
和WIDGET
。改为为每个 UI 文件调用uic.loadUiType
。 - 您缺少对
setupUi()
的调用以初始化 UI。然后你也可以摆脱任何loadUi
.
实施我的建议会产生以下结果:
WIDGET, BASE = uic.loadUiType('1.ui')
WIDGET2, BASE2 = uic.loadUiType('2.ui')
widget = QDockWidget()
class GeoWerkzeug:
def __init__ (self, iface):
self.iface = iface
def initGui (self):
self.startButton = QAction("Plugin starten", self.iface.mainWindow())
self.iface.addPluginToMenu('Plugin', self.startButton)
self.startButton.triggered.connect(self.maskeAufrufen)
def unload (self):
self.iface.removePluginMenu('Plugin', self.startButton)
def maskeAufrufen (self):
# add DockWidget to GUI
self.iface.addDockWidget(QtCore.Qt.RightDockWidgetArea, widget)
widget.setAllowedAreas(QtCore.Qt.RightDockWidgetArea)
# set first window as content of the DockWidget
self.gui = MainWindow(self)
widget.setWidget(self.gui)
class MainWindow(BASE, WIDGET):
def __init__(self, parent=None):
super(MainWindow, self).__init__()
self.setupUi(self)
self.window_second.clicked.connect(self.next_window)
def next_window(self):
# set second window as content of the DockWidget
window_the_second=Second_window()
widget.setWidget(window_the_second)
class Second_window(BASE2, WIDGET2):
def __init__(self):
super(Second_window, self).__init__()
self.setupUi(self)