0

我在 PyQGIS 中编写了一个插件,其中包含几个 Ui(使用 QT Designer)。当我在 QGIS Python 控制台中运行代码时,它运行得非常好。现在我想将它作为经典的 QGIS 插件在公司内部提供(从菜单栏中开始)。它总是与以前的插件配合得很好,但总是只有一个 Ui。

其核心是三个重要文件。1. __init __.py,2.geowerkzeug.py,负责从菜单开始,3.function.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 上的第一个类。窗口将出现。但是如果我点击一个按钮切换到下一个 Ui(类),Ui 不会改变。我的插件中共有 17 个 Ui。这里我只展示两个类作为例子。

现在是function.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)

我最大的理解问题是如何正确地将我的代码从功能.py(在控制台中运行)与其他两个文件链接起来。下一个问题是我什至没有收到可以构建的错误消息。该插件在菜单栏中,可以启动,但之后我无法继续。我希望我的解释是可以理解的。

4

1 回答 1

0

导致第二个窗口不出现的主要问题是您从不显示QDockWidget. 随着widget.setWidget(window_the_second)您设置内容,但它不会使窗口出现。

在显示第一个窗口的方法中,使用self.iface.addDockWidget(QtCore.Qt.RightDockWidgetArea, widget)

然后将您的第一个窗口设置为该dockwidget ( widget.setWidget(self.gui)) 的内容。

总的来说,有些事情有点混乱,所以我将尝试澄清两点。

  1. 窗口的内容是通过子类化的结果来设置的uic.loadUiType。为了让第二个窗口显示您的第二个 ui,您不能将相同的BASEWIDGET. 而是调用uic.loadUiType您的每个 UI 文件。
  2. 您错过了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)
于 2021-08-21T19:08:18.323 回答