2017-09-05 15 views
0

現在、Python 2.7とPyQt 4のQGIS用のプラグインを開発中です。プラグインには、設定タブを開くたびに再生成されるマップレイヤのチェックリスト(アイテムリスト、無関係かもしれません) 。設定ボタンをクリックするたびに再生成するQCheckBoxesのチェック可能なリストを作成することはできましたが、これは優れた機能的なものからまだ遠いです。わかったように、私の問題は主に親子関係とレイアウトの削除です。動的に変更可能なQCheckBoxリスト

def cBoxChecked(self, cBox): 
    """ Add functionality to ScrollArea checkboxes.""" 
    if cBox.isChecked(): 
      if cBox.text() not in api.selected_upload_layers: 
       api.selected_upload_layers.append(cBox.text()) 
    else: 
      try: 
       api.selected_upload_layers.remove(cBox.text()) 
      except Exception as e: 
       print str(e) 

今Alhtough私は例外を取得しないと、リストが再生され、次のよう

self.layers = qgis_api.get_layers() 
    #ScrollArea setup 
    if (api.selected_upload_layers == [] and 
     api.project.layerTreeRoot().children() != []): 
     self.tmp_layers = qgis_api.get_layers() 
     self.layout = QVBoxLayout(self.settingsDock.groupBox) 
     self.scroll = QScrollArea() 
     self.layout.addWidget(self.scroll) 
     self.scroll.setWidgetResizable(True) 
     self.scroll.setFixedHeight(111) 
     self.scrollContent = QWidget(self.scroll) 
     self.scrollLayout = QVBoxLayout(self.scrollContent) 
     self.scrollContent.setLayout(self.scrollLayout) 
     self.scroll.setWidget(self.scrollContent) 

    i = 0 
    self.checkboxes = [] 
    for layer in self.layers: 
     self.checkboxes.append(QCheckBox("{0}".format(layer.name()))) 
     self.checkboxes[i].stateChanged.connect(lambda checked, i = i : self.cBoxChecked(self.checkboxes[i])) #inverts logic if run every time 
     # check logic 
     if i < len(self.layers)-1: 
      i += 1 
    # Create checkboxes first time 
    if not api.upload: #api.upload becomes true when clicked save in settings 
     for i in range(0, len(self.layers)): 
      try: 
       self.scrollLayout.addWidget(self.checkboxes[i]) 
       self.checkboxes[i].setChecked(True) 
      except Exception as e: 
       print str(e) 
    # compare layer list at creation and now to notice difference 
    elif self.tmp_layers != self.layers: 
     for i in range(0, self.scrollLayout.count()): 
      self.scrollLayout.removeItem(self.scrollLayout.itemAt(0)) 
      try: # delete old layer items 
       for i in range(0, len(self.layers)): 
        self.scrollLayout.addWidget(self.checkboxes[i]) 
        self.checkboxes[i].setChecked(True) 
      except Exception as e: 
       print str(e) 

機能cBoxCheckedは()です。私は新しいものの下に古いリストがあることに気づいています。つまり、レイアウトを正しく削除していないということです(レイアウトの削除にはさまざまな質問がありますが)。それを要約する。この具体的な例では、レイアウトを破棄して再作成する最も便利な方法と、親子QObject関係を把握する方法は何ですか?私が気になるもう一つの質問は、新しい設定タブを開くたびに、ラムダ関数のロジック復帰があり、特定のCheckBoxを選択する際に重労働が起こっているようです。それを修正するには? ありがとうございました:)

答えて

0

私はそれを修正しました。主な問題はremoveItemメソッドで、これは計画通りには機能しませんでした。すべてが混乱していましたが。私は今何をしましたか?私は空のリストとしてクラスの初期化時にチェックボックスのリストを作成し、正しい条件で私はそれが初めてSettingsDockが呼び出されたかどうかをチェックしているか、レイヤーインターフェイスリストで何か変更された後に呼び出されます。コードは次のようなものです。コメントで何かが正しく説明されていない場合は、なぜ私がそのようにしたのか尋ねてください。次のように乾杯

self.layers = qgis_api.get_layers() 
    reduced_layers = [] 
    # reduced_layers is list variable which is populated with all layers 
    # without redundant ones (same names of multiple files .shp/.shx/.dbf) 
    # shapefile file format 
    for layer in self.layers: 
     if layer.name() not in reduced_layers: 
      reduced_layers.append(layer.name()) 

    # ScrollArea setup 
    # Set up settingsDock.groupBox as a parent of Vertical layout 
    # Check if Settings was clicked before api.upload would be handy for 
    # that, scroll is QScrollArea and is added as widget with layout as 
    # parent, after that I set up Scroll Content as widget with scroll 
    # as parent, while scroll Layout is Vertical layout with scrollContent 
    # as parent, but then i use scroll.setWidget method to define it as 
    # a parent to scrollContent 
    if (api.selected_upload_layers == [] and 
     api.project.layerTreeRoot().children() != []): 
     self.tmp_layers = qgis_api.get_layers() 
     self.layout = QVBoxLayout(self.settingsDock.groupBox) 
     self.scroll = QScrollArea() 
     # self.layout.addWidget(self.scroll) 
     self.scroll.setWidgetResizable(True) 
     self.scroll.setFixedHeight(111) 
     self.layout.addWidget(self.scroll) 
     self.scrollContent = QWidget(self.scroll) 
     self.scrollLayout = QVBoxLayout(self.scrollContent) 
     self.scroll.setWidget(self.scrollContent) 

    # As self.checkboxes are initialized as empty list, here are we 
    # generating a list of QCheckBox items with layer names(if there are 
    # multiple layers with same name(shapefile format), only one will be 
    # added as checkbox 
    # After generating checkboxes list we use it to populate widgets, 
    # QCheckBoxes in ScrollLayout, and set it in default as Checked 
    # This is basically 1st time initialization 
    if self.checkboxes == []: 
     try: 
      for i in range(0, len(self.layers)): 
       if self.layers[i].name() not in map(lambda x: x.text(), 
                self.checkboxes): 
        self.checkboxes.append(QCheckBox('{}'.format(
              self.layers[i].name()))) 
      for i in range(0, len(self.checkboxes)): 
       self.scrollLayout.addWidget(self.checkboxes[i]) 
       self.checkboxes[i].setChecked(True) 
       api.selected_upload_layers = map(lambda x: x.text(), 
               self.checkboxes) 
     except Exception as e: 
      print str(e) 

    # if checkboxes are different from layer list (that is generated) in 
    # the moment of clicking show settings which basically indicates that 
    # interface layer list has been chaged, we must update checkboxes 
    # To update checkboxes list it's firstly deleted with ScrollContent 
    elif map(lambda x: x.text(), self.checkboxes) != reduced_layers: 
     num = self.scrollLayout.count() 
     self.scrollLayout.removeWidget(self.scrollContent) 
     self.scrollContent.deleteLater() 
     self.scrollContent = QWidget(self.scroll) 
     self.scrollLayout = QVBoxLayout(self.scrollContent) 
     self.scroll.setWidget(self.scrollContent) 
     try: 
      self.checkboxes = [] 
      for i in range(0, len(self.layers)): 
       if self.layers[i].name() not in map(lambda x: x.text(), self.checkboxes): 
        self.checkboxes.append(QCheckBox('{}'.format(
              self.layers[i].name()))) 
      for i in range(0, len(self.checkboxes)): 
       self.scrollLayout.addWidget(self.checkboxes[i]) 
       self.checkboxes[i].setChecked(True) 
     except Exception as e: 
      print (e) 

    for i in range(0, len(self.checkboxes)): 
     self.checkboxes[i].stateChanged.connect(lambda checked, i=i: 
              self.checkBoxChecked()) 

checkBoxChecked機能は()です:

def checkBoxChecked(self): 
    """Add functionality to ScrollArea checkboxes.""" 
    #print api.selected_upload_layers 
    indices = [] 
    for i in range(0, len(self.checkboxes)): 
     if self.checkboxes[i].isChecked(): 
      # print cBox.isChecked() 
      print self.checkboxes[i].text() + " is selected" 
      indices.append(i) 
     else: 
      print self.checkboxes[i].text() + " is deselected" 

    api.selected_upload_layers = [map(lambda x: x.text(), self.checkboxes)[i] for i in indices] 
関連する問題