2014-04-08 14 views
3

첫 번째는 python과 pyside가 처음입니다.PySide QTreeWidget clear()로 인해 충돌이 발생합니다.

세 가지 다른 폴더 구조를 나타내는 QTreeWidgets이 세 가지 있습니다. 3 개 모두 연속으로 지우려고하면 응용 프로그램이 충돌합니다.

widgets = [ self.Delete_treeWidget01, self.Delete_treeWidget02, self.Delete_treeWidget03 ] 
for widget in widgets: 
    widget.clear() 

는 또한 또한 같은 방식으로 충돌하게
widgets = [ self.treeWidget01, self.treeWidget02, self.treeWidget03 ] 
for widget in widgets: 
    aList = (range(widget.topLevelItemCount())) 
    for i in aList[::-1]: 
     widget.takeTopLevelItem(i) 

예를

을 위해, 그것을 다른 방법을 취소하는 것을 시도했다.

나는 "디버그"를 클릭하고 시각적 인 스튜디오는 나에게이 메시지를 주었다 0x000000006E9D2C68 (QtGui4.dll)에서

처리되지 않은 예외 mayapy.exe에서 : 가 0xc0000005 : 액세스 위반 읽기 위치 내지 0xFFFFFFFFFFFFFFFF합니다.

(나는 마야의 I 주로 코드.이 그러나 독립이기 때문에, 더 마야가 포함되지, 마야 파이썬 인터프리터와 이클립스를 사용하고 있기 때문에 마야를 말한다.)

내가 계층 구조에서 폴더를 제거 그 QTreeWidgets은 정확한 것을 보여주기 위해 다시 나타 내기 위해 그것을 지우고 싶습니다.

내가봤을 때 어떤 사람들은 스레딩과 관련이 있다고 말하고 있지만 파이썬과 파이사이드에 익숙하지 않은 나는 물건을 쓰는 방법조차 모른다.

누구나 어떻게 할 수 있습니까?

편집 :

import os 
import sys 
from PySide import QtGui, QtCore 
from Toolbox_Test_UI import Ui_MirrorFolderCreation 
from PySide.QtGui import QMainWindow, QApplication 


class MainWindow(QMainWindow, Ui_MirrorFolderCreation): 
    def __init__(self): 
     super(MainWindow, self).__init__() 
     self.setupUi(self) 

     # Connects the buttons 
     self.Delete_pushButton01.clicked.connect(lambda: self.folderDialog('delete1_dir')) 
     self.Delete_pushButton02.clicked.connect(lambda: self.folderDialog('delete2_dir')) 
     self.Delete_pushButton03.clicked.connect(lambda: self.folderDialog('delete3_dir')) 

     self.Delete_deletePushButton.clicked.connect(lambda: self.deleteFolders()) 
     self.Delete_populatePushButton.clicked.connect(lambda: self.populateTreeViews()) 

     self.Delete_treeWidget01.itemClicked.connect(lambda: self.findMirroredItem()) 

     # Change resize mode 
     headers = [self.Delete_treeWidget01.header(), self.Delete_treeWidget02.header(), self.Delete_treeWidget03.header()] 
     for head in headers: 
      head.setResizeMode(0, QtGui.QHeaderView.ResizeToContents) 

    def findMirroredItem(self): 
     ''' find a item mirrored in widget 2 and 3 ''' 
     #self.deselectTreeWidgetsItem() 
     widgets = [self.Delete_treeWidget02, self.Delete_treeWidget03] 

     for eachWidget in widgets: 
      self.selectMirroredItems(eachWidget) 

    def folderDialog(self, arg): 
     ''' Set lineEdits''' 
     dialog = QtGui.QFileDialog() 

     path = dialog.getExistingDirectory(self, "Select Folder", os.getcwd()) 

     if path: 

      if arg == 'delete1_dir': 
       self.Delete_lineEdit01.setText(path) 

      elif arg == 'delete2_dir': 
       self.Delete_lineEdit02.setText(path) 

      elif arg == 'delete3_dir': 
       self.Delete_lineEdit03.setText(path) 


    def populateTreeViews(self): 
     ''' poplute the widgets''' 
     widgets = { self.Delete_treeWidget01:self.Delete_lineEdit01, self.Delete_treeWidget02:self.Delete_lineEdit02, self.Delete_treeWidget03:self.Delete_lineEdit03 } 

     for treeWidget, lineEdit in widgets.iteritems(): 
      folderPath = lineEdit.text() 

      if folderPath: 
       treeWidget.clear() 
       self.populateTreeWidgetSearch(treeWidget, folderPath) 


    def populateTreeWidgetSearch(self, treeWidget, folderPath): 
     rootTreeView = None 
     def searchFolder(folder, rootTreeView): 
      folders = os.listdir(folder) 
      for eachSubFolder in folders: 
       childFolder = os.path.join(folder, eachSubFolder) 
       if os.path.isdir(childFolder): 
        if rootTreeView is None: 
         rootTreeView = treeWidget.invisibleRootItem() 

        item = QtGui.QTreeWidgetItem(rootTreeView) 
        item.setText(0, eachSubFolder) 
        item.setExpanded(True) 
        item.parent() 

        treeWidget.addTopLevelItem(item) 

        if os.listdir(childFolder): 
         searchFolder(childFolder, item) 

     if folderPath: 
      searchFolder(folderPath, rootTreeView) 


    def deleteFolders(self): 
     def countFolder(folder): 
      folders = os.listdir(folder) 
      for eachSubFolder in folders: 
       eachSubFolder = os.path.join(folder, eachSubFolder) 
       if os.path.isdir(eachSubFolder): 
        self.foIndex += 1 
        if os.listdir(eachSubFolder): 
         countFolder(eachSubFolder) 
       else: 
        self.fiIndex += 1 


     def findFolders(): 
      folderPath = [] 
      widgets = {self.Delete_treeWidget01:self.Delete_lineEdit01, self.Delete_treeWidget02:self.Delete_lineEdit02, self.Delete_treeWidget03:self.Delete_lineEdit03} 
      for treeWidget, lineEdit in widgets.iteritems(): 
       selectedItems = treeWidget.selectedItems() 
       for item in selectedItems: 
        basePath = lineEdit.text() 
        if basePath: 
         treeWidgetHierarchy = self.getTreePath(item) 
         folderPath.append(os.path.join(basePath, treeWidgetHierarchy)) 

      return folderPath 

     infoDict = [] 
     for eachFolder in findFolders(): 
      self.fiIndex = 0 
      self.foIndex = 0  
      countFolder(eachFolder) 
      infoDict.append({'deletionFolder':eachFolder, 'files':self.fiIndex, 'folders':self.foIndex}) 

     self.populateTreeViews() 


    def deselectTreeWidgetsItem(self): 
     # Deselect everything from previews selection 
     widgets = [self.Delete_treeWidget02, self.Delete_treeWidget03] 
     for eachWidget in widgets: 
      for eachSel in eachWidget.selectedItems(): 
       eachSel.setSelected(False) 

    def selectMirroredItems(self, widget): 
     # Get selected item 
     item = self.Delete_treeWidget01.selectedItems()[0] 

     # Path to the selected item 
     itemChilds = self.getTreePath(item) 

     # Find all top items to iterate through 
     topItems = widget.findItems(itemChilds.split('/')[0],QtCore.Qt.MatchExactly,0) 

     # Default state of variables 
     itemFound = None 
     listCheck = [] 
     index = 1 

     if topItems: 
      TreeWidgetItems = QtGui.QTreeWidgetItemIterator(topItems[0]) 
      TreeWidgetItemList = self.remakeList(TreeWidgetItems) 

      for child in itemChilds.split('/'): 
       index = index + 1 
       for item in TreeWidgetItemList: 
        itemlist = self.getTreePath(item) 
        if child == item.text(0): 
         listCheck.append(item.text(0)) 
         if (itemlist in itemChilds) and (len(itemChilds.split('/')) < index): 
          itemFound = item 

      if itemFound: 
       widget.scrollToItem(itemFound) 
       itemFound.setSelected(True) 

    def remakeList(self, treeWidgetList): 
     itemList = [] 
     for it in treeWidgetList: 
      itemList.append(it.value()) 

     return itemList 

    def getTreePath(self, item): 
     path = [] 
     while item is not None: 
      path.append(str(item.text(0))) 
      item = item.parent() 
     return '/'.join(reversed(path)) 


if __name__ == '__main__': 
    app = QApplication(sys.argv) 
    frame = MainWindow() 
    frame.show()  
    app.exec_() 

이 창 코드 :

# -*- coding: utf-8 -*- 

# Form implementation generated from reading ui file 'C:/Users/stmahe1/GoogleDrive_Group3/TA_SpaceShooter/scripts/WIP/mattias/PipelineToolbox/Mirror/ui/Toolbox_Test.ui' 
# 
# Created: Tue Apr 08 13:19:23 2014 
#  by: pyside-uic 0.2.15 running on PySide 1.2.1 
# 
# WARNING! All changes made in this file will be lost! 

from PySide import QtCore, QtGui 

class Ui_MirrorFolderCreation(object): 
    def setupUi(self, MirrorFolderCreation): 
     MirrorFolderCreation.setObjectName("MirrorFolderCreation") 
     MirrorFolderCreation.resize(807, 626) 
     self.centralwidget = QtGui.QWidget(MirrorFolderCreation) 
     self.centralwidget.setObjectName("centralwidget") 
     self.verticalLayout_8 = QtGui.QVBoxLayout(self.centralwidget) 
     self.verticalLayout_8.setObjectName("verticalLayout_8") 
     self.verticalLayout_4 = QtGui.QVBoxLayout() 
     self.verticalLayout_4.setObjectName("verticalLayout_4") 
     self.label_6 = QtGui.QLabel(self.centralwidget) 
     font = QtGui.QFont() 
     font.setFamily("Orator Std") 
     font.setPointSize(11) 
     font.setWeight(75) 
     font.setBold(True) 
     self.label_6.setFont(font) 
     self.label_6.setObjectName("label_6") 
     self.verticalLayout_4.addWidget(self.label_6) 
     self.horizontalLayout_4 = QtGui.QHBoxLayout() 
     self.horizontalLayout_4.setObjectName("horizontalLayout_4") 
     self.verticalLayout_6 = QtGui.QVBoxLayout() 
     self.verticalLayout_6.setObjectName("verticalLayout_6") 
     self.horizontalLayout_20 = QtGui.QHBoxLayout() 
     self.horizontalLayout_20.setObjectName("horizontalLayout_20") 
     self.Delete_lineEdit01 = QtGui.QLineEdit(self.centralwidget) 
     self.Delete_lineEdit01.setObjectName("Delete_lineEdit01") 
     self.horizontalLayout_20.addWidget(self.Delete_lineEdit01) 
     self.Delete_pushButton01 = QtGui.QPushButton(self.centralwidget) 
     self.Delete_pushButton01.setMaximumSize(QtCore.QSize(30, 16777215)) 
     self.Delete_pushButton01.setObjectName("Delete_pushButton01") 
     self.horizontalLayout_20.addWidget(self.Delete_pushButton01) 
     self.verticalLayout_6.addLayout(self.horizontalLayout_20) 
     self.Delete_treeWidget01 = QtGui.QTreeWidget(self.centralwidget) 
     self.Delete_treeWidget01.setEnabled(True) 
     self.Delete_treeWidget01.setObjectName("Delete_treeWidget01") 
     self.Delete_treeWidget01.header().setVisible(False) 
     self.Delete_treeWidget01.header().setStretchLastSection(False) 
     self.verticalLayout_6.addWidget(self.Delete_treeWidget01) 
     self.horizontalLayout_4.addLayout(self.verticalLayout_6) 
     self.verticalLayout_5 = QtGui.QVBoxLayout() 
     self.verticalLayout_5.setObjectName("verticalLayout_5") 
     self.horizontalLayout_19 = QtGui.QHBoxLayout() 
     self.horizontalLayout_19.setObjectName("horizontalLayout_19") 
     self.Delete_lineEdit02 = QtGui.QLineEdit(self.centralwidget) 
     self.Delete_lineEdit02.setObjectName("Delete_lineEdit02") 
     self.horizontalLayout_19.addWidget(self.Delete_lineEdit02) 
     self.Delete_pushButton02 = QtGui.QPushButton(self.centralwidget) 
     self.Delete_pushButton02.setMaximumSize(QtCore.QSize(30, 16777215)) 
     self.Delete_pushButton02.setObjectName("Delete_pushButton02") 
     self.horizontalLayout_19.addWidget(self.Delete_pushButton02) 
     self.verticalLayout_5.addLayout(self.horizontalLayout_19) 
     self.Delete_treeWidget02 = QtGui.QTreeWidget(self.centralwidget) 
     self.Delete_treeWidget02.setObjectName("Delete_treeWidget02") 
     self.Delete_treeWidget02.headerItem().setText(0, "1") 
     self.Delete_treeWidget02.header().setVisible(False) 
     self.Delete_treeWidget02.header().setStretchLastSection(False) 
     self.verticalLayout_5.addWidget(self.Delete_treeWidget02) 
     self.horizontalLayout_4.addLayout(self.verticalLayout_5) 
     self.verticalLayout_7 = QtGui.QVBoxLayout() 
     self.verticalLayout_7.setObjectName("verticalLayout_7") 
     self.horizontalLayout_21 = QtGui.QHBoxLayout() 
     self.horizontalLayout_21.setObjectName("horizontalLayout_21") 
     self.Delete_lineEdit03 = QtGui.QLineEdit(self.centralwidget) 
     self.Delete_lineEdit03.setObjectName("Delete_lineEdit03") 
     self.horizontalLayout_21.addWidget(self.Delete_lineEdit03) 
     self.Delete_pushButton03 = QtGui.QPushButton(self.centralwidget) 
     self.Delete_pushButton03.setMaximumSize(QtCore.QSize(30, 16777215)) 
     self.Delete_pushButton03.setObjectName("Delete_pushButton03") 
     self.horizontalLayout_21.addWidget(self.Delete_pushButton03) 
     self.verticalLayout_7.addLayout(self.horizontalLayout_21) 
     self.Delete_treeWidget03 = QtGui.QTreeWidget(self.centralwidget) 
     self.Delete_treeWidget03.setObjectName("Delete_treeWidget03") 
     self.Delete_treeWidget03.headerItem().setText(0, "1") 
     self.Delete_treeWidget03.header().setVisible(False) 
     self.verticalLayout_7.addWidget(self.Delete_treeWidget03) 
     self.horizontalLayout_4.addLayout(self.verticalLayout_7) 
     self.verticalLayout_4.addLayout(self.horizontalLayout_4) 
     self.horizontalLayout_5 = QtGui.QHBoxLayout() 
     self.horizontalLayout_5.setObjectName("horizontalLayout_5") 
     self.Delete_populatePushButton = QtGui.QPushButton(self.centralwidget) 
     self.Delete_populatePushButton.setObjectName("Delete_populatePushButton") 
     self.horizontalLayout_5.addWidget(self.Delete_populatePushButton) 
     spacerItem = QtGui.QSpacerItem(20, 20, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Minimum) 
     self.horizontalLayout_5.addItem(spacerItem) 
     self.Delete_deletePushButton = QtGui.QPushButton(self.centralwidget) 
     self.Delete_deletePushButton.setObjectName("Delete_deletePushButton") 
     self.horizontalLayout_5.addWidget(self.Delete_deletePushButton) 
     self.verticalLayout_4.addLayout(self.horizontalLayout_5) 
     self.verticalLayout_8.addLayout(self.verticalLayout_4) 
     self.gridLayout_4 = QtGui.QGridLayout() 
     self.gridLayout_4.setObjectName("gridLayout_4") 
     self.verticalLayout_8.addLayout(self.gridLayout_4) 
     MirrorFolderCreation.setCentralWidget(self.centralwidget) 
     self.actionExit = QtGui.QAction(MirrorFolderCreation) 
     self.actionExit.setObjectName("actionExit") 
     self.actionLoad_preset = QtGui.QAction(MirrorFolderCreation) 
     self.actionLoad_preset.setObjectName("actionLoad_preset") 
     self.actionSave_Preset = QtGui.QAction(MirrorFolderCreation) 
     self.actionSave_Preset.setObjectName("actionSave_Preset") 

     self.retranslateUi(MirrorFolderCreation) 
     QtCore.QMetaObject.connectSlotsByName(MirrorFolderCreation) 
     MirrorFolderCreation.setTabOrder(self.Delete_lineEdit01, self.Delete_lineEdit02) 
     MirrorFolderCreation.setTabOrder(self.Delete_lineEdit02, self.Delete_lineEdit03) 
     MirrorFolderCreation.setTabOrder(self.Delete_lineEdit03, self.Delete_pushButton01) 
     MirrorFolderCreation.setTabOrder(self.Delete_pushButton01, self.Delete_pushButton02) 
     MirrorFolderCreation.setTabOrder(self.Delete_pushButton02, self.Delete_pushButton03) 
     MirrorFolderCreation.setTabOrder(self.Delete_pushButton03, self.Delete_populatePushButton) 
     MirrorFolderCreation.setTabOrder(self.Delete_populatePushButton, self.Delete_deletePushButton) 
     MirrorFolderCreation.setTabOrder(self.Delete_deletePushButton, self.Delete_treeWidget01) 
     MirrorFolderCreation.setTabOrder(self.Delete_treeWidget01, self.Delete_treeWidget02) 
     MirrorFolderCreation.setTabOrder(self.Delete_treeWidget02, self.Delete_treeWidget03) 

    def retranslateUi(self, MirrorFolderCreation): 
     MirrorFolderCreation.setWindowTitle(QtGui.QApplication.translate("MirrorFolderCreation", "Technical Artist Toolbox", None, QtGui.QApplication.UnicodeUTF8)) 
     self.label_6.setText(QtGui.QApplication.translate("MirrorFolderCreation", "Mirrored Deletion of Folders", None, QtGui.QApplication.UnicodeUTF8)) 
     self.Delete_pushButton01.setText(QtGui.QApplication.translate("MirrorFolderCreation", "...", None, QtGui.QApplication.UnicodeUTF8)) 
     self.Delete_pushButton02.setText(QtGui.QApplication.translate("MirrorFolderCreation", "...", None, QtGui.QApplication.UnicodeUTF8)) 
     self.Delete_pushButton03.setText(QtGui.QApplication.translate("MirrorFolderCreation", "...", None, QtGui.QApplication.UnicodeUTF8)) 
     self.Delete_populatePushButton.setText(QtGui.QApplication.translate("MirrorFolderCreation", "Update", None, QtGui.QApplication.UnicodeUTF8)) 
     self.Delete_deletePushButton.setText(QtGui.QApplication.translate("MirrorFolderCreation", "Delete", None, QtGui.QApplication.UnicodeUTF8)) 
     self.actionExit.setText(QtGui.QApplication.translate("MirrorFolderCreation", "Exit", None, QtGui.QApplication.UnicodeUTF8)) 
     self.actionLoad_preset.setText(QtGui.QApplication.translate("MirrorFolderCreation", "Load Preset", None, QtGui.QApplication.UnicodeUTF8)) 
     self.actionSave_Preset.setText(QtGui.QApplication.translate("MirrorFolderCreation", "Save Preset", None, QtGui.QApplication.UnicodeUTF8)) 

후 일부는 더 나는 위젯에서 선택한 무언가가 있기 때문에 아마도 테스트 (발견이 작동하는지 findMirroredItem()을 실행하지 않으면), 모든 항목의 선택을 먼저 취소하려면 도움이되지 않습니다.

첫 번째 위젯을 클릭하면 다른 두 개에서 비슷한 객체를 선택하려고 시도합니다. 첫 번째 위젯을 클릭하지 않으면 원하는 횟수만큼 다시로드하거나 채울 수 있으며 충돌하지 않습니다. 내가 선택한 항목을 다시로드하거나 채우려고하면 결국 충돌이 발생합니다.

+1

우리가 문제를 올바르게 재현 할 수 있도록 소극적인 작업 예제를 게시 해주세요. –

+0

예,하지만이 예제는 정확하게 최소한의 것은 아닙니다 ... 죄송합니다. 예를 게시하면 내 선택 때문일 가능성이 높습니다. – Jerakin

+1

게시 한 코드를 살펴보고 문제를 재현하지 않아도되는 내용을 제거 할 수 있습니다 (예 : 기능을 삭제하고 문제를 보여주는 작업을 수행 할 수없는 경우). - 그러나 당신은 여전히 ​​기능의 일부를 제거 할 수 있습니다). – Schollii

답변

3

QTreeWidgetItem을 첫 번째 인수로 사용하면 QTreeWidgetItemIterator의 PySide 버그가 원인 인 것으로 보입니다. QTreeWidget이 첫 번째 인수로 전달되면 문제가 사라집니다. 이 버그는 동등한 PyQt4 코드에서는 발생하지 않습니다.

예제 코드

selectMirroredItems에 다음 줄을 개정하여 고정 할 수 있습니다

# TreeWidgetItems = QtGui.QTreeWidgetItemIterator(topItems[0]) 
    TreeWidgetItems = QtGui.QTreeWidgetItemIterator(widget) 

내가 시도의 문제에 가지 않았더라도 단순히 QTreeWidgetItemIterator 반복하는합니다 (segfault의 원인이 충분히 것 같다 최소한의 테스트 케이스를 작성하는 것).

PySide 버그를보고 할 수 있습니다 here.

+0

그걸 고쳐 줘! 정말 고맙습니다! – Jerakin