Hi all,

I think I need some MVC help once again:

I am using a custom item delegate that uses the bottom 20 pixels of a cell in a table view for a QComboBox (the rest will be static content). I can create the editor in the right spot etc, but I can't figure out how to close it again when the user clicks into the upper part of the cell. I tried all sorts of events and signals in the view, the delegate and the editor itself but to no avail.
This is the state of things:

The initial table:


The table with the open editor after clicking into the bottom 20 pixels of a cell:


The table after I click away from the editor but into the same cell, in which case I'd like to close it and show the initial state as seen above, but I just can't figure out how to.


Attached is the working code to produce the above images.

Any help would be greatly appreciated!

Cheers,
frank


--

ohufxLogo 50x50 <http://www.ohufx.com>    
*vfx compositing <http://ohufx.com/compositing.html> | *workflow customisation and consulting <http://ohufx.com/customising.html>* *
                *<http://ohufx.com/compositing.html>*
<http://www.nukepedia.com/nubridge>       
        

Your gateway to over 1,000 free tools... right inside of Nuke <http://www.nukepedia.com/nubridge>

# simple table to compare versions of the same shot acros different sequences

from PySide2 import QtWidgets
from PySide2 import QtGui
from PySide2 import QtCore

class VersionChoser(QtWidgets.QComboBox):
    def __init__(self, parent=None):
        super(VersionChoser, self).__init__(parent)
        self.setFocusPolicy(QtCore.Qt.StrongFocus)
   
class VersionTableModel(QtCore.QAbstractTableModel):
    def __init__(self, parent=None):
        super(VersionTableModel, self).__init__(parent)

    def rowCount(self, index=None):
        return 4

    def columnCount(self, index=None):
        return 6

    def data(self, index, role):
        if role == QtCore.Qt.DisplayRole:
            try:
                return "{}/{}".format(index.row(), index.column())
            except TypeError:
                return None

    def flags(self, index):
        flags = super(VersionTableModel, self).flags(index)
        flags |= QtCore.Qt.ItemIsEditable
        return flags

class VersionTableView(QtWidgets.QTableView):
    def __init__(self, parent=None):
        super(VersionTableView, self).__init__(parent)
        self.setFrameStyle(QtWidgets.QFrame.NoFrame)
        self.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)

    def setModel(self, model):
        super(VersionTableView, self).setModel(model)
        self.resizeColumnsToContents()
        self.resizeRowsToContents()

    def minimumSizeHint(self):
        return QtCore.QSize(self.width(), self.rowHeight(0) + self.horizontalHeader().height())

    def mousePressEvent(self, event):
        # edit cells when the right area is clicked
        super(VersionTableView, self).mousePressEvent(event)
        if not event.button() == QtCore.Qt.LeftButton:
            return
        
        index = self.indexAt(event.pos())
        editorHeight = self.itemDelegate().editorHeight
        editor_tl = self.mapToGlobal(self.visualRect(index).bottomLeft() + QtCore.QPoint(self.verticalHeader().width(), 2))
        editor_br = self.mapToGlobal(self.visualRect(index).bottomRight() + QtCore.QPoint(self.verticalHeader().width(), 0) + QtCore.QPoint(0, editorHeight))
        editorArea = QtCore.QRect(editor_tl, editor_br)
        cursorPos = QtGui.QCursor().pos()
        if editorArea.contains(cursorPos):
            # Click was inside of editor area so open it for the index
            self.setCurrentIndex(index)
            self.edit(index)
        else:
            # Can't get this to work. I want to close the editor here (without committing any data).
            print "\tclicked off - I want to close teh editor now if it's open" * 50

class VersionSyncWindow(QtWidgets.QWidget):
    '''Main GUI for the version sync app'''

    def __init__(self, parent=None):
        super(VersionSyncWindow, self).__init__(parent)
        self.setWindowFlags(QtCore.Qt.Tool)
        self.initUI()
        self.__prepModel()
        self.connectSignals()
    
    def __prepModel(self):
        '''Deal with proxy models and model/view assignments'''
        self.versionModel = VersionTableModel()
        self.tableViewReference.setModel(self.versionModel)
    
    def connectSignals(self):
        # perform the requested version sync
        self.btnBox.rejected.connect(self.close)

    def initUI(self):      
        # layouts
        mainLayout = QtWidgets.QVBoxLayout()
        self.setLayout(mainLayout)

        # widgets
        self.tableViewReference = VersionTableView()
        self.tableViewReference.setSelectionMode(QtWidgets.QAbstractItemView.NoSelection)
        self.tableViewReference.setFocusPolicy(QtCore.Qt.NoFocus)
        self.tableViewReference.setItemDelegate(VersionItemDelegate())
        self.btnBox = QtWidgets.QDialogButtonBox(QtWidgets.QDialogButtonBox.Apply | QtWidgets.QDialogButtonBox.Cancel)
        mainLayout.addWidget(self.tableViewReference)
        mainLayout.addWidget(self.btnBox)
   
class VersionItemDelegate(QtWidgets.QStyledItemDelegate):

    def __init__(self, parent=None):
        super(VersionItemDelegate, self).__init__(parent)
        self.editorHeight = 20

    def createEditor(self, parent, option, index):
        '''Creates a combo box to chose the version to sync in case tehre are mote than one used in a sequence.
        Only show the editor if the mouse click ocurrs in the area where the editor lives.
        '''
        editor = QtWidgets.QComboBox(parent)
        editor.setMaximumHeight(self.editorHeight)
        return editor

    def setEditorData(self, editor, index):
        for n in xrange(10):
            editor.addItem(str(n))
        editor.showPopup()

    def updateEditorGeometry(self, editor, option, index):
        '''Move combo box down and make sure it fills the width of the cell'''
        editor.move(option.rect.topLeft().x(), option.rect.height() - editor.height())
        editor.resize(option.rect.width(), editor.height())
       
    def paint(self, painter, option, index):
        super(VersionItemDelegate, self).paint(painter, option, index)
        # paint bottom bit
        rect_to_paint = QtCore.QRect(option.rect.topLeft().x(), option.rect.bottomLeft().y() - self.editorHeight,
                                   option.rect.width(), option.rect.height()*.3) 
        
        painter.setPen(QtGui.QPen(QtCore.Qt.NoPen))
        painter.setBrush(QtGui.QBrush(QtCore.Qt.darkGreen))
        painter.drawRect(rect_to_paint)

    def sizeHint(self, option, index):
        '''Adjust size hint for table view to resize to contents properly'''
        return QtCore.QSize(200, 70)


if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication([])
    mainWindow = VersionSyncWindow()
    mainWindow.show()
    sys.exit(app.exec_())
_______________________________________________
PySide mailing list
[email protected]
http://lists.qt-project.org/mailman/listinfo/pyside

Reply via email to