Hi *, attached, you will find an app to reproduce some strangeness with QSpinBox behaviour.
Problem: reimplemented QSpinBox don't get focus events and doesn't behave correctly on up/down cursor key events (value doesn't change). This happens at least with SuSE-Versions 8.0 and 8.1, with all PyQt-Versions up to the snapshot from 2003/01/11. If you have a couple of spare minutes, please run the attached script from a shell, <tab><cursor up><cursor down><tab><space> and watch console output. I get: (# comments added) # startup SpinBox event: ChildInserted SpinBox event: ChildInserted PushButton event: Move PushButton event: Resize PushButton event: Show SpinBox event: Move SpinBox event: Resize SpinBox event: Show SpinBox event: LayoutHint PushButton event: Paint PushButton event: WindowActivate SpinBox event: WindowActivate PushButton event: FocusIn PushButton focusInEvent PushButton event: Paint # startup done # <tab> PushButton event: AccelOverride PushButton event: KeyPress PushButton event: FocusOut PushButton focusOutEvent PushButton event: Paint SpinBox event: KeyRelease # PushButton class gets focus event correctly, SpinBox don't # <cursor up> SpinBox event: AccelOverride SpinBox event: KeyPress SpinBox event: KeyRelease # SpinBox doesn't change the value, consequently no valueChanged signal # <cursor down> SpinBox event: AccelOverride SpinBox event: KeyPress SpinBox event: KeyRelease # again.. # <tab> SpinBox event: AccelOverride PushButton event: FocusIn PushButton focusInEvent PushButton event: Paint PushButton event: KeyRelease # again, PushButton class gets focus event correctly # <space> PushButton event: AccelOverride PushButton event: KeyPress PushButton event: Paint PushButton event: KeyRelease PushButton event: Paint close app PushButton event: WindowDeactivate SpinBox event: WindowDeactivate PushButton event: FocusOut PushButton focusOutEvent PushButton event: Hide SpinBox event: Hide # finished If your output differs significantly from this log, please give me a note, mentioning your OS, Qt, and PyQt versions. This is a long standing problem, I'm suffering from and would like to get solved somehow. Therefore, I'm going to translate this app to c++ in order to check this behaviour of Qt directly soon. Interesting side note: I needed to prepare the event() handlers not to call the base class in order to avoid an attribute error during qApp.quit(). Phil, it appears, that the QSpinBox base class disappears while subclassed SpinBox event() handler is active. This doesn't look right to me. TIA, Pete
#!/usr/bin/env python # sbtest v0.1: investigate QSpinBox strangeness # # Copyright 2002 Hans-Peter Jansen <[EMAIL PROTECTED]> # # This program is placed under the GNU General Public License V.2 import sys from qt import * qEvent = { 0: "None", 1: "Timer", 2: "MouseButtonPress", 3: "MouseButtonRelease", 4: "MouseButtonDblClick", 5: "MouseMove", 6: "KeyPress", 7: "KeyRelease", 8: "FocusIn", 9: "FocusOut", 10: "Enter", 11: "Leave", 12: "Paint", 13: "Move", 14: "Resize", 15: "Create", 16: "Destroy", 17: "Show", 18: "Hide", 19: "Close", 20: "Quit", 21: "Reparent", 22: "ShowMinimized", 23: "ShowNormal", 24: "WindowActivate", 25: "WindowDeactivate", 26: "ShowToParent", 27: "HideToParent", 28: "ShowMaximized", 29: "ShowFullScreen", 30: "Accel", 31: "Wheel", 32: "AccelAvailable", 33: "CaptionChange", 34: "IconChange", 35: "ParentFontChange", 36: "ApplicationFontChange", 37: "ParentPaletteChange", 38: "ApplicationPaletteChange", 39: "PaletteChange", 40: "Clipboard", 42: "Speech", 50: "SockAct", 51: "AccelOverride", 52: "DeferredDelete", 60: "DragEnter", 61: "DragMove", 62: "DragLeave", 63: "Drop", 64: "DragResponse", 70: "ChildInserted", 71: "ChildRemoved", 72: "LayoutHint", 73: "ShowWindowRequest", 80: "ActivateControl", 81: "DeactivateControl", 82: "ContextMenu", 83: "IMStart", 84: "IMCompose", 85: "IMEnd", 86: "Accessibility", 87: "Tablet" } probmsg = """\ Problem: reimplemented QSpinBox below don't get focus events and doesn't behave correctly on up/down cursor keys!\ """ class SpinBox(QSpinBox): def __init__(self, minValue, maxValue, step = 1, parent = None, name = None): self.lastval = None QSpinBox.__init__(self, minValue, maxValue, step, parent, name) def event(self, e): t = e.type() if t in qEvent.keys(): print "SpinBox event:", qEvent[t] else: print "unknown SpinBox event:", t # this seems to be necessary because of races with qApp.quit() if QSpinBox: return QSpinBox.event(self, e) else: return 0 def focusInEvent(self, e): self.lastval = self.value() print "SpinBox focusInEvent", self.lastval return QSpinBox.focusInEvent(self, e) def focusOutEvent(self, e): v = self.value() print "SpinBox focusOutEvent", v, self.lastval if self.lastval != v: emit(SIGNAL("valueChanged(int)"), (v)) return QSpinBox.focusOutEvent(self, e) class PushButton(QPushButton): def __init__(self, text = None, parent = None, name = None): QPushButton.__init__(self, text, parent, name) def event(self, e): t = e.type() if t in qEvent.keys(): print "PushButton event:", qEvent[t] else: print "unknown PushButton event:", t # this seems to be necessary because of races with qApp.quit() if QPushButton: return QPushButton.event(self, e) else: return 0 def focusInEvent(self, e): print "PushButton focusInEvent" return QPushButton.focusInEvent(self, e) def focusOutEvent(self, e): print "PushButton focusOutEvent" return QPushButton.focusOutEvent(self, e) class sbTest(QWidget): def __init__(self, parent = None, name = None, fl = 0): QWidget.__init__(self, parent, name, fl) self.setCaption("QSpinBox test") self.value = 42 vbox = QVBoxLayout(self, 4, -1, "vbox") qb = PushButton("Quit", self, "qb") vbox.addWidget(qb) l = QLabel(probmsg, self, "tl") vbox.addWidget(l) sb = SpinBox(1, 200, 1, self, "sb") sb.setValue(self.value) vbox.addWidget(sb) self.connect(sb, SIGNAL("valueChanged(int)"), self.changed) self.connect(qb, SIGNAL("clicked()"), self.closeEvent) self.vbox = vbox def changed(self, v): print "sb changed:", v self.value = v def closeEvent(self, e = None): print "close app" qApp.quit() #sys.exit(0) if __name__ == "__main__": a = QApplication(sys.argv) QObject.connect(a,SIGNAL("lastWindowClosed()"),a,SLOT("quit()")) w = sbTest() a.setMainWidget(w) w.show() a.exec_loop()