Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Language Bindings
  4. Custom dropEvent in TreeWidget: how to find target item (tree item under mouse?)
Forum Updated to NodeBB v4.3 + New Features

Custom dropEvent in TreeWidget: how to find target item (tree item under mouse?)

Scheduled Pinned Locked Moved Language Bindings
3 Posts 2 Posters 5.5k 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
    Alabaster
    wrote on last edited by
    #1

    PyQt4 / Python 3

    I'm dragging text from a listwidget to a treewidget, but I need to override the default drag-and-drop behavior because I'm using a custom TreeWidgetItem class. I cannot figure out how to find the tree item currently under the mouse during a dropEvent. Any help would be much appreciaed!

    A simple sample code is below:

    @
    import sys
    from PyQt4.QtGui import *
    from PyQt4.QtGui import *

    class EditScreen(QWidget):
    def init(self):
    super(EditScreen, self).init()
    self.initUI()

    def initUI(self):
        global tree
        global listbox
        self.vbox = QVBoxLayout()
        self.hbox = QHBoxLayout()
        
        
        listbox = QListWidget()
        listbox.setDragEnabled(True)
        listbox.setSelectionMode(QAbstractItemView.ExtendedSelection) 
        for x in range(1,10):
            item = 'Thing' + str(x)
            listbox.addItem(item)
            
        tree = MyTreeWidget()
        tree.setAcceptDrops(True)
        tree.setSelectionMode(QAbstractItemView.ExtendedSelection) 
        for x in range(1,5):
            addnewtreeitem = MyTreeItemClass('Category ' + str(x), toplevel=True)
            addnewtreeitem.setExpanded(True)
        
        question = 'Double-clicking a category in the treewidget (right) calls my "addHere" function,'
        question += '\nwhich adds the selected items (from the left) to the treeview after messing with them a bit.'
        question += '\n\nI would like to drag items over from the listwidget, with exactly the same functionality as the double-click.'
        question += '\nbut I do not understand how to find the target item (underneath the mouse) during a dropEvent.'
        question += '\nI need this target item in order to call my "addHere" function.'
        question += '\n\nI cannot use the standard drag-and-drop behavior because I must use a custom TreeWidgetItem class.'
        
        
        questionlabel = QLabel(question)
        self.hbox.addWidget(listbox)
        self.hbox.addWidget(tree)
        
        
        self.vbox.addWidget(questionlabel)
        
        self.vbox.addLayout(self.hbox)
        
        self.setLayout(self.vbox)
        self.setWindowTitle('How can I make drag-and-drop perform my "addHere" function?')
        self.show()
        
    def keyPressEvent(self, e):        
        if e.key() == Qt.Key_Delete:
            #print('pressed delete key')
            tree.delButtonPressed()
    

    class MyTreeWidget(QTreeWidget):
    def init(self):
    QTreeWidget.init(self)
    self.itemDoubleClicked.connect(self.addHere)

    def delButtonPressed(self):
        for item in self.selectedItems():
            if item.deletable:
                item.parent.removeChild(item)
                MyTreeItemClass.child_list.remove(item)
        
    def addHere(self, clickeditem, column):
        global listbox
        
        for x in listbox.selectedItems():
            if clickeditem.can_add_here == True:
                print('Adding item(s) here', clickeditem.treetext)
                itemtext = x.text()
                newtreeitem = MyTreeItemClass(itemtext, parent=clickeditem)
                clickeditem.setExpanded(False)  # need to use false to counter-act the double-clicking action?
            else:
               print('cannot add to this item')
    

    class MyTreeItemClass(QTreeWidgetItem):
    global tree
    toplevel_list = []
    child_list = []
    def init(self, treetext, toplevel=False, parent=None):
    self.treetext = treetext
    QTreeWidgetItem.init(self, [self.treetext])

        if parent:
            self.parentitem=parent
        
        if toplevel == True:
            self.deletable = False
            self.can_add_here = True
            MyTreeItemClass.toplevel_list.append(self)
            tree.addTopLevelItem(self)
            
        else:
            self.deletable = True
            self.can_add_here = False
            itemnum = int(self.treetext[-1])
            
            if itemnum % 2 == 0:
                self.setForeground(0,QBrush(Qt.blue))
            else:
                self.setForeground(0,QBrush(Qt.red))
    
            if itemnum % 3 == 0:
                self.setBackground(0,QBrush(Qt.lightGray))
    
            if itemnum % 4 == 0:
                self.setBackground(0,QBrush(Qt.black))
                self.setForeground(0,QBrush(Qt.white))
    
            MyTreeItemClass.child_list.append(self)
            self.parentitem.addChild(self)
    

    def main():
    app = QApplication(sys.argv)
    editscreen = EditScreen()
    sys.exit(app.exec_())

    main()
    @

    1 Reply Last reply
    0
    • jazzycamelJ Offline
      jazzycamelJ Offline
      jazzycamel
      wrote on last edited by
      #2

      "QTreeWidget.itemAt":http://doc.qt.digia.com/qt/qtreewidget.html#itemAt is what your looking for. Try adding the following to your MyTreeWidget class:

      @
      def dropEvent(self, e):
      item=self.itemAt(e.pos())
      if item: self.addHere(item)
      e.accept()
      @

      You might also want to do the following in the constructor to stop the default expand behavior:

      @
      self.setExpandsOnDoubleClick(False)
      @

      Hope this helps ;o)

      For the avoidance of doubt:

      1. All my code samples (C++ or Python) are tested before posting
      2. As of 23/03/20, my Python code is formatted to PEP-8 standards using black from the PSF (https://github.com/psf/black)
      1 Reply Last reply
      0
      • A Offline
        A Offline
        Alabaster
        wrote on last edited by
        #3

        This worked great! Thanks so much.

        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