2
votes

I'm sorry but just a beginner of Python. I just want to change index of QStackedWidget by the item click of QTreeWidget. I searched for the tutorials of SIGNAL and SLOT online, but just cannot solve the problem. The parameters in QTreeWidget signal and QStackedWidget slot are not fitted.

self.connect(qtree, QtCore.SIGNAL("itemClicked(QTreeWidgetItem*,int)"), stack, QtCore.SLOT("setCurrentIndex(int)"))

And I tried this:

qtree.itemClicked.connect(stack.setCurrentIndex)

It just showed the error:

TypeError: setCurrentIndex(self, int): argument 1 has unexpected type 'QTreeWidgetItem'

I think there may be a method, but I cannot find on the network.

Like this:

 from PyQt4.QtGui import *
 from PyQt4.QtCore import *
 import sys

 class StockDialog(QDialog):
     def __init__(self,parent=None):
         super(StockDialog,self).__init__(parent)

         mainSplitter=QSplitter(Qt.Horizontal)

         treewidget = QTreeWidget(mainSplitter)
         treewidget.setHeaderLabels(["Tree"])
         treeroot = QTreeWidgetItem(treewidget, ["Stack"])
         treeitem1 = QTreeWidgetItem(["WorkSpace"])
         treeitem2 = QTreeWidgetItem(["About"])
         treeroot.addChild(treeitem1)
         treeroot.addChild(treeitem2)

         stack=QStackedWidget(mainSplitter)
         stack.setFrameStyle(QFrame.Panel|QFrame.Raised)

         stackworkspace=StackWorkSpace()
         stackabout=StackAbout()
         stack.addWidget(stackworkspace)
         stack.addWidget(stackabout)

         closePushButton=QPushButton(self.tr("Close"))

         self.connect(treewidget,
            SIGNAL("itemClicked(int)"),
            stack,SLOT("setCurrentIndex(int)"))
         self.connect(closePushButton,
            SIGNAL("clicked()"),
            self,SLOT("close()"))

         layout=QVBoxLayout(self)
         layout.addWidget(mainSplitter)
         layout.addWidget(closePushButton)
         self.setLayout(layout)

 class StackWorkSpace(QWidget):
     def __init__(self,parent=None):
         super(StackWorkSpace,self).__init__(parent)
         widget1=QTextEdit(self.tr("WorkSpace"))
         widget2=QTextEdit(self.tr("WorkSpace"))

         layout=QGridLayout(self)
         layout.addWidget(widget1,0,0)
         layout.addWidget(widget2,0,1)

 class StackAbout(QDialog):
     def __init__(self,parent=None):
         super(StackAbout,self).__init__(parent)
         self.setStyleSheet("background: red")

 app=QApplication(sys.argv)
 main=StockDialog()
 main.show()
 app.exec_()

When change the QTreeWidget to the QListWidget in StockDialog class, it works.

class StockDialog(QDialog):
     def __init__(self,parent=None):
         super(StockDialog,self).__init__(parent)

         mainSplitter=QSplitter(Qt.Horizontal)

         listwidget=QListWidget(mainSplitter)
         listwidget.insertItem(0,self.tr("WorkSpace"))
         listwidget.insertItem(1,self.tr("About"))

         stack=QStackedWidget(mainSplitter)
         stack.setFrameStyle(QFrame.Panel|QFrame.Raised)

         stackworkspace=StackWorkSpace()
         stackabout=StackAbout()
         stack.addWidget(stackworkspace)
         stack.addWidget(stackabout)

         closePushButton=QPushButton(self.tr("Close"))

         self.connect(listwidget,
            SIGNAL("currentRowChanged(int)"),
            stack,SLOT("setCurrentIndex(int)"))
         self.connect(closePushButton,
            SIGNAL("clicked()"),
            self,SLOT("close()"))

         layout=QVBoxLayout(self)
         layout.addWidget(mainSplitter)
         layout.addWidget(closePushButton)
         self.setLayout(layout)

Now, I want to do this with QTreeWidget, how can I do?

1
What feature do you need from QTreeWidget, so what relationship exists between a particular QTreeWidget item and a QStackedWidget index?eyllanesc
Why do not you answer what I asked you? A list has as an inherent element to the number of edge, on the other hand in a QTreeWidget it does not have it since the structure is of a tree.eyllanesc
@eyllanesc I'm sorry. I want to learn how to do the same thing by using QTreeWidget. For Example, when I click the "WorkSpace" item in the tree, the QStackedWidget can just display the index defined in the "StackWorkSpace" class.Mersper
That example is very simple so it does not convince me much, please give me another example that has more detail.eyllanesc
You will only have the WorkSpace and About items in QTreeWidget, and then when you click on these you want StackWorkSpace or StackAbout to be displayed, respectively. I am right?eyllanesc

1 Answers

3
votes

The strategy to solve this problem is to save the index information associated with each widget in the QTreeWidgetItem. QTreeWidgetItem has the setData() method that allows us to save information in the item and in this case we will save the index. The index is returned every time you add a widget to QStackedWidget through addWidget(), so in summary we will do the following:

treeitem1.setData(0, Qt.UserRole, stack.addWidget(stackworkspace))
treeitem2.setData(0, Qt.UserRole, stack.addWidget(stackabout))

After connecting the itemClicked signal of QTreeWidget, this returns the column and the item pressed, with this information we obtain the QStackedWidget index for it we recover the data saved through the function data():

treewidget.itemClicked.connect(lambda item, column: stack.setCurrentIndex(item.data(column, Qt.UserRole))
if item.data(column, Qt.UserRole) is not None else None)

The necessary code can be found in the following section:

class StockDialog(QDialog):
    def __init__(self, parent=None):
        super(StockDialog, self).__init__(parent)

        mainSplitter = QSplitter(Qt.Horizontal)

        treewidget = QTreeWidget(mainSplitter)
        treewidget.setHeaderLabels(["Tree"])
        treeroot = QTreeWidgetItem(treewidget, ["Stack"])
        treeitem1 = QTreeWidgetItem(["WorkSpace"])
        treeitem2 = QTreeWidgetItem(["About"])
        treeroot.addChild(treeitem1)
        treeroot.addChild(treeitem2)

        stack = QStackedWidget(mainSplitter)
        stack.setFrameStyle(QFrame.Panel | QFrame.Raised)

        stackworkspace = StackWorkSpace()
        stackabout = StackAbout()

        treeitem1.setData(0, Qt.UserRole, stack.addWidget(stackworkspace))
        treeitem2.setData(0, Qt.UserRole, stack.addWidget(stackabout))

        closePushButton = QPushButton(self.tr("Close"))

        treewidget.itemClicked.connect(lambda item, column: stack.setCurrentIndex(item.data(column, Qt.UserRole))
        if item.data(column, Qt.UserRole) is not None else None)

        layout = QVBoxLayout(self)
        layout.addWidget(mainSplitter)
        layout.addWidget(closePushButton)
        self.setLayout(layout)