[PyKDE] working code

Andrew Dalke adalke at mindspring.com
Fri Apr 19 08:38:15 BST 2002


Here's working code for a context menu in the column header of a QTable.
All it really does is support right mouse button clicks in the QHeader.

Enjoy.

					Andrew
					dalke at dalkescientific.com

# Experiment with doing a context menu popup in the column headers

# Yeah, this is global data.  It's an experiment, after all.
import random
names = ["Andrew", "Brandy", "Cindy", "Dylan", "Ewan", "Fran", "Geoff",
         "Hernando", "Igor", "Jeremy", "Kelly", "Linda", "Martha"]
data = []
for name in names:
    data.append( {
        "name": name,
        "len": len(name),
        "random": "%3.2f" % random.random(),
        })
keys = data[0].keys()
keys.sort()

import sys
from qt import *
from qttable import *

# Convert right mouse button clicks (which is a request for a context
# menu for X and MS Windows) into a new signal.
class HeaderHandler(QObject):
    def eventFilter(self, obj, event):
        if event.type() == QEvent.MouseButtonPress and \
           event.button() == QMouseEvent.RightButton:
                obj.emit(PYSIGNAL("headerContextMenu(int,const QPoint&)"),
                         (obj.sectionAt(event.x()), event.globalPos()))
                return 1
        return 0
        

class DataTable(QTable):
    def __init__(self, *args):
        QTable.__init__(self, *args)
        self.rows = data
        self.insertRows(0, len(self.rows))

        self.header_handler = HeaderHandler(self)
        
        self.horizontalHeader().installEventFilter(self.header_handler)
        self.setColumnMovingEnabled(1)

        self.insertColumnAt("name", 0)
        
        QObject.connect(self,
                        SIGNAL("contextMenuRequested(int,int,const QPoint&)"),
                        self.contextMenuRequested)
        QObject.connect(self.horizontalHeader(),
                        PYSIGNAL("headerContextMenu(int,const QPoint&)"),
                        self.headerContextMenu)

    def headerContextMenu(self, orig_colno, pos):
        colno = orig_colno
        if colno == -1:
            colno = self.numCols() - 1
        menu = QPopupMenu()

        # Need to keep an extra reference to the lambda function,
        # since PyQt doesn't.
        funcs = []
        for key in keys:
            f = lambda id, key=key:self.insertColumnAt(key, colno + 1)
            funcs.append(f)
            menu.insertItem("Insert " + key, f)

        menu.insertSeparator()

        f = lambda id: self.removeColumn(colno)
        funcs.append(f)
        menu.insertItem("Delete", f, 0, 100)
        # Check if the mouse button was not on any column
        if orig_colno == -1:
            menu.setItemEnabled(100, 0)

        
        
        menu.setMouseTracking(1)
        menu.exec_loop(pos)

    def contextMenuRequested(self, row, col, pos):
        print "contextMenuRequested", row, col, pos.x(), pos.y()
        
        
    def insertColumnAt(self, name, col = 0):
        assert col >= 0, col
        self.insertColumns(col)
        self.horizontalHeader().setLabel(col, name)
        for row, data in zip(range(len(self.rows)), self.rows):
            self.setText(row, col, str(data[name]))


if __name__ == '__main__':
    a = QApplication(sys.argv)
    w = DataTable()
    w.setCaption("Blah blah")
    a.setMainWidget(w)
    w.show()
    a.exec_loop()





More information about the PyQt mailing list