[PyQt] Signal on Selection in QTreeView

fossks at cox.net fossks at cox.net
Tue Mar 18 16:46:06 GMT 2008


Phil/Andreas,

     I've been experimenting again using some of the recommendations and some examples I have found.   Please look at the new example I am working with, which is below.

    I can now have a reaction to a selected item in a list.  When something is selected, the 'slot' function is called and is run.  Great!   In this case it prints out some details including the number of rows, etc.

    Now I am still trying to access a reference to the selected item so I can pull the data from the original list and display it elsewhere in a different widget.  The original author of this modified program included a function call called "data".   However, I cannot figure out how to use it.  I guess my hangup is the index and role fields.  I don't know what to put in those fields to get the currently selected item.  

    In my case I need the current row, that is the current row number.  I don't need to fiddle around with the row entries as I already have them in the original list. 

   Could someone help me write a simple function called "get_current_row_number", which returns an integer indicating the highlighted row?

Kevin

____________ Code Below ___________________

import re
import operator
import os
import sys 
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyQt4 import QtCore, QtGui
 
 
def main(): 
    app = QApplication(sys.argv) 
    w = MyWindow() 
    w.show() 
    sys.exit(app.exec_()) 
 
####################################################################

class MyClass: 
     def slot(self, selected, deselected): 
         print len(selected), "items selected" 
         print len(deselected), "items deselected" 

####################################################################
 
 
class MyWindow(QWidget): 
    def __init__(self, *args): 
        QWidget.__init__(self, *args) 

	self.total_list = []
	self.loadDefaults()
# open library file
# read in each line
# if line is video, put in video array, audio..., picture...

	libfile = open(self.MEDIA_LOC + "/mpyqt_library/library.txt","r")
	for count in libfile.readlines():			
		entry = self.parse(count)
		print entry
		self.total_list = self.total_list + [entry]

	self.tabledata = self.total_list


        # create table
#        self.get_table_data()
        self.table = self.createTable() 
         
        # layout
        layout = QVBoxLayout()
        layout.addWidget(self.table) 
        self.setLayout(layout) 

	QObject.connect(self.table.selectionModel(), SIGNAL("selectionChanged(QItemSelection, QItemSelection)"), self.slot) 
 
    def slot(self, selected, deselected): 
	print len(selected), "items selected" 
	print len(deselected), "items deselected" 
	print self.tm.rowCount()
	print QModelIndex()

    def parse(self, libline):
	output = libline.split(" ^ ")
	return output


    def loadDefaults(self):
	count = 0	
	
	self.fileName = QtCore.QDir.homePath() + "/mpyqt.conf"
	f = QtCore.QFile(self.fileName)
	if f.exists():		
		clipfile = open(QtCore.QDir.convertSeparators(self.fileName),"r")	
		for count in clipfile.readlines():
       			if count [0:10] == "MEDIA_LOC=":
      				self.MEDIA_LOC = count[10:-1]


    def get_table_data(self):
        stdouterr = os.popen4("dir c:\\")[1].read()
        lines = stdouterr.splitlines()
        lines = lines[5:]
        lines = lines[:-2]
        self.tabledata = [re.split(r"\s+", line, 4)
                     for line in lines]

    def createTable(self):
        # create the view
        tv = QTableView()

        # set the table model
        header = ['a', 'b', 'c', 'd', 'e','f', 'g', 'h', 'i', 'j' ]
        self.tm = MyTableModel(self.tabledata, header, self) 
        tv.setModel(self.tm)

        # set the minimum size
        tv.setMinimumSize(400, 300)

        # hide grid
        tv.setShowGrid(False)

        # set the font
        font = QFont("Courier New", 8)
        tv.setFont(font)

        # hide vertical header
        vh = tv.verticalHeader()
        vh.setVisible(False)

        # set horizontal header properties
        hh = tv.horizontalHeader()
        hh.setStretchLastSection(True)

        # set column width to fit contents
        tv.resizeColumnsToContents()

        # set row height
        nrows = len(self.tabledata)
        for row in xrange(nrows):
            tv.setRowHeight(row, 18)

        # enable sorting
        tv.setSortingEnabled(True)

        return tv
 
####################################################################
 
class MyTableModel(QAbstractTableModel): 
    def __init__(self, datain, headerdata, parent=None, *args): 
        """ datain: a list of lists
            headerdata: a list of strings
        """
        QAbstractTableModel.__init__(self, parent, *args) 
        self.arraydata = datain
        self.headerdata = headerdata
 
    def rowCount(self, parent=QModelIndex()): 
        return len(self.arraydata) 
 
    def columnCount(self, parent=QModelIndex()): 
        return len(self.arraydata[0]) 
 
    def data(self, index, role): 
        if not index.isValid(): 
            return QVariant() 
        elif role != Qt.DisplayRole: 
            return QVariant() 
        return QVariant(self.arraydata[index.row()][index.column()]) 

    def headerData(self, col, orientation, role):
        if orientation == Qt.Horizontal and role == Qt.DisplayRole:
            return QVariant(self.headerdata[col])
        return QVariant()

    def sort(self, Ncol, order):
        """Sort table by given column number.
        """
        self.emit(SIGNAL("layoutAboutToBeChanged()"))
        self.arraydata = sorted(self.arraydata, key=operator.itemgetter(Ncol))        
        if order == Qt.DescendingOrder:
            self.arraydata.reverse()
        self.emit(SIGNAL("layoutChanged()"))

####################################################################


if __name__ == "__main__": 
    main()


____________ Code Above ___________________



---- Phil Thompson <phil at riverbankcomputing.com> wrote: 
> On Tuesday 18 March 2008, Marius Kintel wrote:
> > On Mar 18, 2008, at 2:57 AM, Kevin Foss wrote:
> > > 	To show you my difficulties, I've tried to test this whole
> > > selection model
> > > capability using an example from David Boddie at Trolltech.  It can
> > > be found
> > > here:
> > >
> > > http://www.opensubscriber.com/message/pyqt@riverbankcomputing.com/8447872
> > >.html
> > >
> > >      	Guess what, even his example doesn't work.  When I run his
> > > example,
> > > nothing is printed when an item is selected.
> >
> > I think I can help.
> > I spend a lot of time figuring out how this works a month or so back.
> > My results can be summed up like this:
> >
> >     ** Never connect a Qt signal to a global python function **
> >
> >     If the python wrapper object dies (common for temporary wrapper
> > objects), the connection goes down with it.
> 
> What makes you say that? The connection has nothing to do with the wrapper 
> object of the emitter.
> 
> > Instead, connect to a 
> > python instance method. This is handled in a special way in SIP making
> > the connection survive the temporary python wrapper object.
> >
> > Taking my own advice, the example program you mention can be fixed by
> > making the slot an instance method instead:
> 
> This should make no difference.
> 
> Phil
> _______________________________________________
> PyQt mailing list    PyQt at riverbankcomputing.com
> http://www.riverbankcomputing.com/mailman/listinfo/pyqt



More information about the PyQt mailing list