[Solved] QT: editable tableview header issue.



  • Involves: python2.7 + pyside

    Delving into modelview programming became complicated after seeing few explanations of the structure involving an editable model; Perusing through forums, source and documentation is only leading me so far.

    My issue currently is trying to edit a tableview header (subclass) entry using a custom delegate.

    I've seen implementations using an mousedoubleclicked event, which seems to be a good start.

    However, understanding is null in regards to a models "index" function, let alone QModelindex.

    Could anyone shed some light on index / createIndex?

    • aside from the text mention in the docs of course*

    @
    class LayerSys(QAbstractItemModel):

    --------------

    On creation do

    --------------

    def init(self):

    Init the parent constructor.

    QAbstractItemModel.init(self)

    Set trackers for the layer system:

    self.layers = {} # Layer dict objects
    self.layerKeys = [] # Layer dict keys

    Set counters for the layer system:

    self.layerCount = 0 # Number of visable layers
    self.layersCreated = 0 # Number of generated layers
    self.frameCount = 0 # Number of visable frames

    -----------------------

    Create a new DopeSheet:

    -----------------------

    def New(self, layers, *args):

    Reset all tracking variables:

    self.layers = {} # Layer dict objects
    self.layerKeys = [] # Layer dict keys
    self.layerCount = 0 # Number of visable layers
    self.frameCount = 0 # Number of visable frames

    Translate the number of layers requested into a list for looping.

    layers = range(layers)

    For the number of requested layers do..

    for layer in layers:

    Check if we are creating a usermade or default layer.

    if len(args) != 0: # User defined

    # Create n' layer with a user defined name.
    self.AddLayer( name=args[0].pop(len(args[0])-1) )
    

    else: # Default naming convention.

    # Create n' layer with a default name.
    self.AddLayer()
    

    -------------------

    Create a new Layer:

    -------------------

    def AddLayer(self, **kwargs):

    Temporary value for the generated/passed layer name.

    layerName = None

    Check if we are using a passed name:

    if 'name' in kwargs: # Using a passed name

    Use the layer name passed by the user.

    layerName = kwargs['name']

    else: # Create a default layer name.

    Create a new layer name.

    layerName = 'Layer_'+str(self.layersCreated+1)

    Start the column/layer insertion process: start,end ( 0,0 = one layer before 0 )

    self.beginInsertColumns(QModelIndex(), 0, 0)

    Create a new layer object:

    self.layers[layerName] = { 'name':layerName } # Create the object
    self.layerKeys.insert(0, layerName) # Add to the name list

    End the insertion process.

    self.endInsertColumns()

    Increase the layer counters:

    self.layerCount += 1 # Number of visable layers
    self.layersCreated += 1 # Number of created layers

    --

    ?

    --

    def index(self, row, column):
    return self.createIndex( 0, column, 0 )

    -----------------------------------------------------

    Return Layer names requested by a LayerView instance:

    -----------------------------------------------------

    def headerData(self, section, orientation, infoToGet):

    Only send information for display purposes.

    if infoToGet == Qt.DisplayRole:

    Only send header/layer information.

    if orientation == Qt.Horizontal:

    # Return a layer Name.
    return self.layers[ self.layerKeys[section] ]['name']
    

    -------------------------------------------------------------------

    Return the number of layers when requested by a LayerView instance:

    -------------------------------------------------------------------

    def columnCount(self, parent):

    Return the number of layers.

    return self.layerCount

    -------------------------------------------------------------------

    Return the number of frames when requested by a LayerView instance:

    -------------------------------------------------------------------

    def rowCount(self, parent):

    Return the number of frames.

    return self.frameCount
    @

    @
    class LayerHeader(QHeaderView):

    ---------------

    On creation do:

    ---------------

    def init(self, parent):

    Init the parent constructor

    QHeaderView.init(self, Qt.Horizontal, parent)

    Connect the DOUBLECLICK event for edit processing.

    self.sectionDoubleClicked.connect( self.onDoubleClick )

    -------------------------------------

    When the header is double clicked do:

    -------------------------------------

    def onDoubleClick(self, layerID):

    Access the required object referenced by layerID

    obj = self.model().index(0, layerID)

    Trigger an edit action for n' object.

    self.edit(obj)
    @



  • Hi,

    I have no experience with pyside and python,
    but as it's Qt under it, perhaps I can help a bit :-)

    A Model index is a representation of an element in a model. This representation is like a hierarchical table (parent, row = child, column). Additionally, there might be extra data to store in this index, so the item can easily be found again in case the client want's to do anything with a model element. This extra data can be an int64 or a pointer.

    This is use full for hierarchical grids, so you could store an internal pointer to an object and need not iterate to find your internal data for an element.

    The method index is the one, the client of the model (e.g. a View) calls to get a valid index. createIndex is the internal function that is called from the model itself to create the QModelIndex object.

    It ensures that all aprameters are set correctly (like the model pointer etc.). The constructor of QModelIndex that is used by createIndex is not usable by derived models.



  • bq. A Model index is a representation of an element in a model. This representation is like a hierarchical table (parent, row = child, column).

    Given that hierarchy, a table header should only contain one row with an index of 0, and any number of columns.

    For example the root header for column 0 being (0,0)
    column 1 (0,1)..etc

    It seems that (0,0), (0,1) actually represent table cells rather than header entries since calling

    @
    varName = self.model().index(0,0, QModelindex() )
    self.edit( varname )
    @

    From the view to returning

    @
    def index(self, row, column, parent):
    return self.createIndex(row, column)
    @

    From the model, results in an error: Editing Failed

    Unless its because an editor delegate isn't attached yet.

    Or it's not possible to edit header entries without creating another subclass of QAbstractitemview..custom painting..
    to use as a table header.



  • The models data is shown in the table, not in the header.

    The header data is represented by headerdata, only with section and orientation. But for header data, there is no flags to specify editable cells.

    That's why editing headers is difficult :-)



  • [quote]That's why editing headers is difficult :-)[/quote]

    Oey, In the back of my mind I was thinking the same thing.

    Aside from a custom widget (have yet to figure out painting),
    editing works if passing header information into an external dialog.

    Not exactly what I intended for the user, but it works :)

    Thank you for your kind help.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.