Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QComboBox with QTreeView popup: how can I have different display in QComboBox label and QComboBox item?

QComboBox with QTreeView popup: how can I have different display in QComboBox label and QComboBox item?

Scheduled Pinned Locked Moved Solved General and Desktop
12 Posts 4 Posters 6.4k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • A Offline
    A Offline
    albertho
    wrote on last edited by A Former User
    #1

    Hello!
    I'm new to Qt. I use python and PyQt4 (Qt 4.8).

    I'm writing an application where user can choose data he wants to display on a graph. These data are contained in stuctures, so their names are of the form:
    "root.struct1.struct2.data0"

    To let the user choose a data, I would like to use a QComboBox with a QTreeView as a popup using model / view approach. QAbstractItemModel subclassing, QTreeView work fine. My problem is that when the user selects a data name in the QTreeView, the QComboBox label displays the last part of the name (e.g. "data0"), which conforms to model / view, but I woud like it to display the whole name (e.g. "root.struct1.struct2.data0")...

    I'm stuck on this problem, so if someone can give me a solution, or explains how QComboBox gets the user selection, I would be very happy! Thanks for any help...

    Here is what I code:
    @

    -- coding: utf-8 --

    from PyQt4 import QtCore, QtGui

    class MyTreeNode(object):

    def init(self,name,parent,data = None):
    self.name = name
    self.parent = parent
    self.data = data
    self.childs = {}

    def addChild(self,name,data):
    try:
    node = self.childs[name]
    except KeyError:
    node = MyTreeNode(name,self,data)
    self.childs[name] = node
    return node

    def getParent(self):
    return self.parent

    def subnode(self,name):
    return self.childs[name]

    def subnodeIndex(self,name):
    return sorted(self.childs.keys()).index(name)

    def subnodeAt(self,index):
    key = sorted(self.childs.keys())[index]
    return self.childs[key]

    def subnodeCount(self):
    return len(self.childs)

    def isRootOf(self,tree):
    return tree.nodeIsRoot(self)

    class MyTree(object):
    def init(self):
    self.root = MyTreeNode(None,None)

    def setitem(self,key,data):
    if type(key) in [list, tuple]:
    node = self.root
    for k in key:
    node = node.addChild(k,data)
    node.data = data
    else:
    self.root.addChild(key,data)

    def getitem(self,key):
    return self.node(key).data

    def nodeIsRoot(self,node):
    return node == self.root

    def node(self,key):
    if type(key) in [list, tuple]:
    node = self.root
    for k in key:
    node = node.subnode(k)
    return node
    else:
    return self.root[key]

    class MyTreeModel(QtCore.QAbstractItemModel):
    def init(self,tree,parent = None):
    super(MyTreeModel,self).init(parent)
    self.tree = tree

    def rowCount(self,parent):
    node = parent.internalPointer()
    if node == None: return self.tree.root.subnodeCount()
    return node.subnodeCount()

    def columnCount(self,parent):
    return 1

    def data(self,index,role):
    if not index.isValid():
    return None
    if role != QtCore.Qt.DisplayRole:
    return None
    node = index.internalPointer()
    return node.name

    def index(self,row,column,parent):
    if not parent.isValid():
    node = self.tree.root
    else:
    node = parent.internalPointer()
    if row >= node.subnodeCount():
    return QtCore.QModelIndex()
    return self.createIndex(row,column,node.subnodeAt(row))

    def parent(self,index):
    """ returns the grand parent of index """
    if not index.isValid():
    return QtCore.QModelIndex()
    node = index.internalPointer()
    nodeParent = node.getParent()
    if nodeParent == None or nodeParent.isRootOf(self.tree):
    return QtCore.QModelIndex()
    row = nodeParent.getParent().subnodeIndex(nodeParent.name)
    return self.createIndex(row,0,nodeParent)

    def headerData(self,section,orientation,role):
    if orientation == QtCore.Qt.Horizontal:
    if role == QtCore.Qt.DisplayRole:
    return 'Data Name'
    return None

    class TreeBox(QtGui.QComboBox):
    """
    All event / skipNextHide stuff was grabbed from the web
    """
    def init(self,parent = None):
    super(TreeBox,self).init(parent)
    self.skipNextHide = False
    self.setView(QtGui.QTreeView(self))
    self.view().viewport().installEventFilter(self)
    self.view().setAlternatingRowColors(True)
    self.setMinimumSize(QtCore.QSize(200,30))

    def eventFilter(self,obj,event):
    if event.type() == QtCore.QEvent.MouseButtonPress:
    if obj == self.view().viewport():
    mouseEvent = QtGui.QMouseEvent(event)
    pos = mouseEvent.pos()
    index = self.view().indexAt(pos)
    if not self.view().visualRect(index).contains(pos):
    self.skipNextHide = True
    return False

    def hidePopup(self):
    if self.skipNextHide:
    self.skipNextHide = False
    else:
    super(TreeBox,self).hidePopup()

    testDataNames = [
    'box0.box00.box000.sensor0.pressure',
    'box0.box00.box000.sensor0.density',
    'box0.box00.box001.sensor0.salinity',
    'box1.box10.sensor0.temperature',
    'box1.box11.sensor0.sound_velocity',
    'box1.box11.box110.sensor0.water',
    'box1.box12.box120.sensor0.pressure'
    ]

    if name == 'main':
    import sys
    import random

    tree = MyTree()
    for dataName in testDataNames:
    tree[dataName.split('.')] = random.random()

    app = QtGui.QApplication(sys.argv)
    app.setStyle('windows')

    treeModel = MyTreeModel(tree)

    comboBox = TreeBox()
    comboBox.setModel(treeModel)

    comboBox.show()

    sys.exit(app.exec_())

    @

    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi and welcome to devnet,

      You could set a custom QStyledItemDelegate where you reimplement the displayText method to return the value you want.

      Hope it helps

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      0
      • A Offline
        A Offline
        albertho
        wrote on last edited by
        #3

        Hi, thanks for your answer...

        But how may I know if displayText is called for display in QTreeView or for display of the QComboBox label?

        1 Reply Last reply
        0
        • A Offline
          A Offline
          albertho
          wrote on last edited by
          #4

          Back again...
          I spent a bit of time reading some Qt tutorials...

          For this problem, as suggest by SGaist, I used a QStyledItemDelegate for my TreeView. According a flag, the displayText method give the long name or short name of the data. This flag value is set in QComboBox showPopup (the flag is set to short name for QTreeView) and QComboBox hidePopup (long name for QComboBox label)...
          This does work...

          1 Reply Last reply
          0
          • SGaistS Offline
            SGaistS Offline
            SGaist
            Lifetime Qt Champion
            wrote on last edited by
            #5

            Nice !

            You can also set a custom QStyleItemDelegate on your combo box depending on what you would like to get shown in it

            Interested in AI ? www.idiap.ch
            Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

            1 Reply Last reply
            0
            • jerome_isAviableJ Offline
              jerome_isAviableJ Offline
              jerome_isAviable
              wrote on last edited by
              #6

              i try to do it and arrive to do... not so difficult to see it...
              but i experiment that the problem after that is QtreeView will be... inside the QComboBox object, and then, when you click for popup the tree, there is no redimension of the little window of the combobox, and also, you have an event click generated inside the QCombobox object...
              so you need after to:
              re-implement the event mouse clicks...
              and re-design the comboBox for be able to change size for reallyu show the opened tree childs at time.... and maybe more...for add slide bar.

              big work, lot of code, eat time... for little render for me, i forget it, but it is possible.
              I don't know why Qt not provide a tool for do it easy... but when you talk around this on the IRC... some peoples (qorks for Qt) don't like this vision of evolution and block... i think too much work.

              1 Reply Last reply
              0
              • A Offline
                A Offline
                albertho
                wrote on last edited by
                #7

                @jerome_isAvailable,
                I think the real work is reading tutorials, testing examples, practising a bit... Qt is a big thing, and like big things, you can't handle every part of it with a two days practise time... It's easy when you know the right way to do it, but you have to work to know.
                I'm quite happy with what I did in two days, it's far to be perfect, but it's really better than what I had before!

                1 Reply Last reply
                0
                • SGaistS Offline
                  SGaistS Offline
                  SGaist
                  Lifetime Qt Champion
                  wrote on last edited by
                  #8

                  Do you mean you want to show a QTreeView in a QComboBox popup ?

                  Interested in AI ? www.idiap.ch
                  Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                  1 Reply Last reply
                  0
                  • jerome_isAviableJ Offline
                    jerome_isAviableJ Offline
                    jerome_isAviable
                    wrote on last edited by
                    #9

                    @albertho: thank you for your help...
                    i would be curious and happy to see your result around this kind of work/experience/practice.
                    Maybe you will be able to pastebin the little code you do for show how you do it well ?
                    For me... after 3 months, 25 cpp files in my application(who is not finish), 14000 lines of codes and 26 postgresql tables used... i consider to not loose my time to do something (who is sure possible to do) who is not my priority and need lot of experience/work/practice/TIME/CODES LINES for see it working.
                    But... maybe i'm wrong and it is possible to do it without loose to much time... and without write to muche lines of codes... i'm sure you will show me. Im' happy you have time for do this, i think this could help the other one who would like to do same (i was one... and i'm interested about your result to).

                    Thank you Albertho.

                    1 Reply Last reply
                    0
                    • A Offline
                      A Offline
                      albertho
                      wrote on last edited by
                      #10

                      @SGaist
                      I solved my problem, thanks to your help!

                      @jerome_isAvailable
                      Well, surely my english writting is not very good. I tried to tell you that I'm a Qt newbie, that I need to work to understand it well... But, within a short time, I was able to put a QTreeView in a QComboBox, and that's fine for me. My test code is in my first post, since I just add less than 10 lines of code. I can't post the whole application...

                      V 1 Reply Last reply
                      0
                      • jerome_isAviableJ Offline
                        jerome_isAviableJ Offline
                        jerome_isAviable
                        wrote on last edited by
                        #11

                        i'm a newbie too... and my english is poor too.
                        no problem, i just would like to know if you could use it well: without any problem from open/close trees and see the little window of the combobox adjust the dimension or not ?
                        Because for me, it was not so simple. But also, not by python, but by C++ coding (but i think it is maybe not so different... except python coding is shorter numbers of lines).

                        I will try your code translated in C++ to, maybe this could help me also in some futur thinks like this style. So i copy your code for translate and use it.

                        thanks albertho.

                        1 Reply Last reply
                        0
                        • A albertho

                          @SGaist
                          I solved my problem, thanks to your help!

                          @jerome_isAvailable
                          Well, surely my english writting is not very good. I tried to tell you that I'm a Qt newbie, that I need to work to understand it well... But, within a short time, I was able to put a QTreeView in a QComboBox, and that's fine for me. My test code is in my first post, since I just add less than 10 lines of code. I can't post the whole application...

                          V Offline
                          V Offline
                          vishumish
                          wrote on last edited by
                          #12

                          Hi @albertho, I am just like you were 2 years back.. a new bee to pyqt. I wanted to have an UI where a QTreeView will get populated inside a QComboBox. Can you help me with an example just to get an idea on how to approach this. Many thanks :)

                          1 Reply Last reply
                          0

                          • Login

                          • Login or register to search.
                          • First post
                            Last post
                          0
                          • Categories
                          • Recent
                          • Tags
                          • Popular
                          • Users
                          • Groups
                          • Search
                          • Get Qt Extensions
                          • Unsolved