[PyKDE] context menu in QHeader

Boudewijn Rempt boud at valdyas.org
Wed Apr 17 23:14:31 BST 2002


On Wednesday 17 April 2002 21:12, Andrew Dalke wrote:
> Boudewijn: (from private email)
>
> > have you tried using the event functions of QWidget? You can catch
> > any mouse event anywhere using them, and then use a QPopupMenu.
>
> A-ha, that works.
>
> [now list email]
>
> > QHeader inherits QWidget, which has a method, mousePressEvent(QEvent ev).
> > You can find out which kind of press occurred, and also the location
> > of the press. From there, it's easy to instantiate and populate a
> > QPopupMenu.
>
> I tried that, but mousePressEvent is a virtual method of the QWidget,
> which (if I understand correctly) means I would need to derive from
> QHeader to get that call.  I tried treating it as a signal, but PyQT
> complained and wouldn't let me.

Yes, I see. You can't subclass QHeader and put your own subclass in QTable.
However, I think (not tested, though), that you can subclass QTable, and have
QTable catch the mouse events; simple artithmetic will then determine whether
the user clicked in the header. There may well be better ways of doing it, but 
that's what I would try. 

Working with QTable is still on my todo -- I've got a database app that's 
built around QListView, and I want to convert it to QTable. But I've not
even started...

>
> In a related question, I want the column headers to provide some
> feedback during mouseover (eg, by having the background become a
> lighter shade of grey).  I tried setting the options that seemed
> even vaguely relevant, but none worked.
>
> It seems I should be able to implement my own paint method to do
> that, but it again requires that I be able to tell the QTable to use
> my derived QHeader and not the default one.
>

<...>

> I (think) I understand.  Again, it's only been a couple of days.  But
> since there was a 'contextMenuRequested' event for the cells I figured
> there would also be a contextMenuRequested signal for the headers, and
> it appears that there isn't.
>

No :-(. It's very sad -- I think that QHeader has reused in the best
OO fashion -- having been used previously in QListView, but without
much thinking.

<...>

>

> I think I follow how events work, it's just that I don't know what to
> do when there isn't the event I'm looking for.  For example, I don't
> recall anything in your book on event filters, nor any example close
> enough to what I'm working on for me to tweak.
>

Well, they are dealt with, passim, in chapter 15. But they are not 
really complex beasts: a simple function that's fed events, and decides
whether to pass them on, or not. They were especially useful when you
wanted a QMultiLineEdit where tab insert \t, instead hopping to the
next widget.

If you create an object derived from QObject, with a function named
eventFilter(self, obj, ev), you can install that object in another QObject, 
with installEventFilter(self, object). This the eventFilter function of
the first object is then called before the events are passed on through the
object itself.

This might actually be the solution for your problem (untested code alert!):

class Filter(QObject):

	def __init__(self, target, *args):
		QObject.__init__(*args)
	    self.target = target

	def eventFilter(self, obj, ev):
		if obj == self.target:
			if ev.type() == QEvent.MouseButtonPress:
				if ev.Button() == Qt.ShiftButton: #or whatever
					self.emit(PYSIGNAL("contextMenuRequested"), (ev,))
					return True
		return False

header = myTable.horizontalHeader()
header.installEventFilter(Filter(myTable)

On the other hand, it might not work...

> > As for the rest: QGrid isn't a widget, but a layout manager, actually.
> > For your purpose, QTable should work best.
>
> My mistake.  I just started with Qt a couple days ago and I'm still
> lost in the maze of different names.  I meant to say QTable.
>

Good luck!

-- 
Boudewijn Rempt | http://www.valdyas.org





More information about the PyQt mailing list