1

我正在用 python 开发一个 QGIS 插件,并在显示我的 GUI 时遇到了障碍。我正在使用插件构建器框架来开发我的插件,但我无法在我的 GUI 的滚动区域中显示一个可检查的组合框。具有核心功能的代码如下。

def run(self):
# Only create GUI ONCE in callback, so that it will only load when the plugin is started
if self.first_start == True:
    self.first_start = False
    # Sets up the pyqt user interface
    self.dlg = EarthingToolDialog()

# Fetching the active layer in the QGIS project
layer = self.iface.activeLayer()

checkable_combo = CheckableComboBox()

# Going through each field of the layer
# and adding field names as items to the 
# combo box

for j,field in enumerate(layer.fields()):    
    checkable_combo.addItem(str(field.name()))

    # Setting the checked state to True by default
    checkable_combo.setItemChecked(j, True) 

# putting the check box inside the scroll area of the GUI
self.dlg.scrollArea.setWidget(checkable_combo)
self.dlg.scrollArea.setMinimumSize(QSize(700,400))   

# show the dialog
self.dlg.show()
# Run the dialog event loop
self.dlg.exec_()    

class EarthingToolDialog(QtWidgets.QDialog, FORM_CLASS):
    def __init__(self, parent=None):
        """Constructor."""
        super(EarthingToolDialog, self).__init__(parent)
        self.setupUi(self)   

class CheckableComboBox(QComboBox):
def __init__(self):
    super().__init__()
    self._changed = False

    self.view().pressed.connect(self.handleItemPressed)

def setItemChecked(self, index, checked=False):
    print('checked')
    item = self.model().item(index, self.modelColumn()) # QStandardItem object
    print(type(item))

    if checked:
        item.setCheckState(Qt.CheckState.Checked)
    else:
        item.setCheckState(Qt.CheckState.Unchecked)
        
def handleItemPressed(self, index):
    print('pressed')
    item = self.model().itemFromIndex(index)

    if item.checkState() == Qt.Checked:
        item.setCheckState(Qt.Unchecked)
    else:
        item.setCheckState(Qt.Checked)
    self._changed = True
    print('set ' +  str(item.checkState()))

def hidePopup(self):
    print('hide')
    if not self._changed:
        super().hidePopup()
    self._changed = False

def itemChecked(self, index):
    print('read')
    item = self.model().item(index, self.modelColumn())
    return item.checkState() == Qt.Checked    

综上所述,run函数是插件加载时调用的主要函数。self.dlg 是实际 pyqt python 用户界面的实例。这是在 EarthingToolDialog 类的帮助下呈现的。可检查的组合框及其功能自包含在 CheckableComboBox 类中。

加载插件但复选框在组合框中不可见时,run 函数执行没有任何错误。在 GUI 的滚动区域上只能看到一个带有项目列表的普通组合框(只是标准的下拉组合框),而不是所需的可检查组合框。CheckableComboBox 类取自https://morioh.com/p/d1e70112347c,它在演示代码中运行良好。

我知道这是一个非常具体的问题,如果有人能弄清楚问题可能是什么,那就太好了。提前致谢!

4

1 回答 1

0
  1. 在 run 函数中,这段代码对我不起作用:

    self.dlg.scrollArea.setWidget(checkable_combo)
    self.dlg.scrollArea.setMinimumSize(QSize(700,400))
    

所以相反,我使用:

layout = QVBoxLayout()
layout.addWidget(checkable_combo)
self.dlg.setLayout(layout)
  1. 我没有直接使用这个类(由于我使用Plugin Builder,它是自动生成的,所以在这里我评论了它):

    class EarthingToolDialog(QtWidgets.QDialog, FORM_CLASS):
        def __init__(self, parent=None):
        """Constructor."""
            super(EarthingToolDialog, self).__init__(parent)
            self.setupUi(self)
    
  2. 现在,为了显示可检查的组合框,CheckableComboBox 构造函数更改为:

    def __init__(self):
        super().__init__()
        self._changed = False
        self.view().pressed.connect(self.handleItemPressed)
        delegate = QtWidgets.QStyledItemDelegate(self.view())
        self.view().setItemDelegate(delegate)
    

最后两行来自此处列出的答案。

代码显示可检查的组合框列表,默认情况下检查所有项目。

于 2022-02-16T20:36:47.540 回答