2

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?

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
Mersper
  • 107
  • 8
  • What feature do you need from QTreeWidget, so what relationship exists between a particular QTreeWidget item and a QStackedWidget index? – eyllanesc Nov 02 '17 at 13:56
  • 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 Nov 03 '17 at 01:30
  • @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 Nov 03 '17 at 01:48
  • That example is very simple so it does not convince me much, please give me another example that has more detail. – eyllanesc Nov 03 '17 at 01:50
  • 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 Nov 03 '17 at 01:53
  • @eyllanesc I prefer more items. Like I have WorkSpace1, WorkSpace2, WorkSpace3 and About items. I want to know how to display different index for each item. – Mersper Nov 03 '17 at 02:17
  • Test my solution – eyllanesc Nov 03 '17 at 03:03

1 Answers1

3

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)
eyllanesc
  • 235,170
  • 19
  • 170
  • 241
  • But the code should be: (item.data(column, Qt.UserRole).toInt()[0] – Mersper Nov 03 '17 at 07:33
  • @Mersper In the version of PyQt that I have the conversion is not necessary (to me it works correctly), but of all my idea is correct, please if my answer will help you the usual is mark it as correct. – eyllanesc Nov 03 '17 at 08:34