[PyQt] How to make QTreeWidget dragging semi-transparent and keep itemWidgets

Han Jiang oglops at gmail.com
Thu Aug 14 02:02:02 BST 2014


i have a treeWidget with itemWidget set on columns, but after dragging the
widgets are gone, and the dropping indicator is opaque

1. How can i make the widget persist after dropping
2. How to make dropping indicator transparent ? ( i'm on centos 6.5, the
compositing manager is not running)

screenshots are here:

http://i.stack.imgur.com/d4sFP.png
http://i.stack.imgur.com/2Oa9A.png

executable example:

    #!/usr/bin/env python2
    import os
    import sys
    import re

    from PyQt4 import QtGui, QtCore
    from PyQt4.QtCore import Qt, QString


    class MyTreeWidget(QtGui.QTreeWidget):
        def __init__(self, parent=None):
            super(MyTreeWidget, self).__init__(parent)

    class CommandWidget(QtGui.QDialog):

        def __init__(self, parent=None, level=0,script='echo
/path/to/script'):
            super(CommandWidget, self).__init__()
            self.layout = QtGui.QHBoxLayout(self)

            browseBtn = QtGui.QPushButton(parent)

            browseBtn.setMinimumSize(QtCore.QSize(0, 25))
            # level, path = val

            # levelNum = re.search('(?<=level).+', level).group()
            browseBtn.setText('%s : %s' % (level, script))
            self._level = int(level)
            self._script = script
            browseBtn.setStyleSheet("text-align: left")

            self.layout.addWidget(browseBtn)

            # self.updateGeometry()
            self.browseBtn = browseBtn
            # self.layout.addWidget(browseBtn)
            self.browseBtn.clicked.connect(self.browseCommandScript)
            self.browseBtn.setIconSize(QtCore.QSize(64, 64))

        def browseCommandScript(self):
            script = QtGui.QFileDialog.getOpenFileName(
                self, 'Select Script file', '/home/xxx/python', ".py Files
(*.py);;Executable Files (*)")
            if script:
                self._script = script
                button_label = re.search('[^\\/]*$',script).group()
                self.browseBtn.setText(('%s : %s' % (self._level,
button_label)))

        @property
        def level(self):
            return self._level

        @level.setter
        def level(self, value):
            self._level = value

        @property
        def script(self):
            return self._script

        @script.setter
        def script(self, value):
            self._script = value


    class MyLineEdit(QtGui.QWidget):
        def __init__(self,value=None,parent=None):
            super(MyLineEdit,self).__init__(parent)
            self.layout = QtGui.QHBoxLayout(self)
            self.layout.setSpacing(0)
            self.layout.setMargin(3)

            self.lineEdit = QtGui.QLineEdit(value)
            spacer1 = QtGui.QSpacerItem(20, 20,
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)
            spacer2 = QtGui.QSpacerItem(20, 20,
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)

            self.lineEdit.setContentsMargins(2,2,2,2)
            self.lineEdit.setAlignment(Qt.AlignHCenter)

            self.layout.addItem(spacer1)
            self.layout.addWidget(self.lineEdit)
            self.layout.addItem(spacer2)

            self.lineEdit.setMaximumSize(QtCore.QSize(70, 25))
            self.lineEdit.textEdited.connect(self._update_item_widget_data)

        def text(self):
            return self.lineEdit.text()

        def setText(self,text):
            return self.lineEdit.setText(text)


        def _update_item_widget_data(self,text):
            # print 'update',text
            self.treeWidgetItem.setData(1,Qt.UserRole,text)

    class TheUI(QtGui.QDialog):

        def __init__(self, args=None, parent=None):
            super(TheUI, self).__init__(parent)
            self.layout = QtGui.QVBoxLayout(self)
            treeWidget = MyTreeWidget()

            button = QtGui.QPushButton('Add')
            self.layout.addWidget(treeWidget)
            self.cssEditTE = QtGui.QPlainTextEdit()

            self.layout.addWidget(button)
            self.layout.addWidget(self.cssEditTE)

            self.cssEditTE.textChanged.connect(self._update_css)

            treeWidget.setHeaderHidden(True)
            treeWidget.setRootIsDecorated(False)

            layout = QtGui.QHBoxLayout(self)
            rootDecorationCB = QtGui.QCheckBox('RootIsDecorated')
            layout.addWidget(rootDecorationCB)
            self.layout.addLayout(layout)

rootDecorationCB.stateChanged.connect(self._update_root_decorated)

            indentationSlider = QtGui.QSlider()
            indentationSlider.setOrientation(Qt.Horizontal)
            indentationSlider.setRange(0,100)
            indentationSlider.setValue(20)
            indentationSlider.valueChanged.connect(self._alter_indentation)
            layout.addWidget(indentationSlider)


            self.layout.setStretchFactor(treeWidget,1)

            self.treeWidget = treeWidget
            self.button = button
            self.button.clicked.connect(lambda *x: self.addCmd())

            HEADERS = ( "script", "chunksize", "mem" )
            self.treeWidget.setHeaderLabels(HEADERS)
            self.treeWidget.setColumnCount( len(HEADERS) )

            self.treeWidget.setColumnWidth(0,200)
            self.treeWidget.header().show()

            for i in range(len(HEADERS)):

self.treeWidget.headerItem().setTextAlignment(i,Qt.AlignHCenter)



self.treeWidget.setDragDropMode(QtGui.QAbstractItemView.InternalMove)

            self.treeWidget.setIndentation(60)

            self.resize(500,700)

            for i in xrange(2):
                self.addCmd()

            item = self.addCmd()
            self.addCmd(parent = item)
            self.addCmd(parent = item)
            item = self.addCmd()

            item=self.addCmd(parent = item)
            self.addCmd(parent = item)
            self.addCmd()

            self.treeWidget.setColumnWidth(0,200)

        def addCmd(self, level=0, script='echo
/path/to/script',parent=None):
            'add a level to tree widget'

            root = self.treeWidget.invisibleRootItem()

            if parent is None:
                parent = root
            item = QtGui.QTreeWidgetItem(parent)
            # item =
QtGui.QTreeWidgetItem(self.treeWidget.invisibleRootItem())
            item.setFlags(item.flags() | QtCore.Qt.ItemIsDropEnabled)

            existingLevels = self.treeWidget.topLevelItemCount()
            # level, path = val
            # level = level % existingLevels

            cmdWidget = CommandWidget(self.treeWidget, existingLevels,
script)
            self.treeWidget.setItemWidget(item, 0, cmdWidget)

            line_edit_1 = MyLineEdit('1')
            line_edit_2 = MyLineEdit('200')

            self.treeWidget.setItemWidget(item, 1, line_edit_1)
            self.treeWidget.setItemWidget(item, 2, line_edit_2)

            item.setExpanded(True)
            return item

        def _update_css(self):
            self.treeWidget.setStyleSheet(self.cssEditTE.toPlainText())

        def _update_root_decorated(self,state):
            if state == Qt.Checked:
                self.treeWidget.setRootIsDecorated(True)
            else:
                self.treeWidget.setRootIsDecorated(False)
            self.treeWidget.updateGeometries()

        def _alter_indentation(self,value):
            print value
            self.treeWidget.setIndentation(value)
            self.treeWidget.updateGeometries()



    if __name__ == '__main__':
        app = QtGui.QApplication(sys.argv)
        gui = TheUI()
        gui.show()
        app.exec_()
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.riverbankcomputing.com/pipermail/pyqt/attachments/20140814/66871484/attachment-0001.html>


More information about the PyQt mailing list