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()

Reply via email to