I'm following Mark Summerfield's Rapid GUI Programming with Python and Qt
which is using PyQt4. I'd prefer to be working with PyQt5, but I have both on my machine. I'm on the second exercise in the book, which is as follows:
from __future__ import division
import sys
from math import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
class Form(QDialog):
def __init__(self, parent=None):
super(Form, self).__init__(parent)
self.browser = QTextBrowser()
self.lineedit = QLineEdit("Type an expression and press Enter")
self.lineedit.selectAll()
layout = QVBoxLayout()
layout.addWidget(self.browser)
layout.addWidget(self.lineedit)
self.setLayout(layout)
self.lineedit.setFocus()
# This line fails:
self.connect(self.lineedit, SIGNAL("returnPressed()"), self.updateUi)
self.setWindowTitle("Calculate")
def updateUi(self):
try:
text = unicode(self.lineedit.text())
self.browser.append("%s = <b>%s</b>" % (text, eval(text)))
except:
self.browser.append(
"<font color=red>%s is invalid!</font>" % text)
app = QApplication(sys.argv)
form = Form()
form.show()
app.exec_()
When I run the script with PyQt4 (and swapping PyQt5.QtWidgets
with PyQt4.QtGui
) it runs fine, but with PyQt5 it fails with:
Traceback (most recent call last):
File "calculate.pyw", line 32, in <module>
form = Form()
File "calculate.pyw", line 19, in __init__
self.connect(self.lineedit, SIGNAL("returnProcessed()"), self.updateUi)
AttributeError: 'Form' object has no attribute 'connect'
I did some digging but apparently there are no changes to connect so I thought this might be an inheritance issue, however when I run dir(QDialog)
in both PyQt4 and PyQt5 connect
only appears in PyQt4 (outputs trimmed, full output further down):
Python 3.4.1 (default, Aug 24 2014, 21:32:40)
[GCC 4.2.1 Compatible Apple LLVM 5.1 (clang-503.0.40)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from PyQt5.QtWidgets import *
>>> dir(QDialog)
[..., 'colorCount', 'connectNotify', 'contentsMargins', ...]
Python 2.7.8 (default, Aug 24 2014, 21:26:19)
[GCC 4.2.1 Compatible Apple LLVM 5.1 (clang-503.0.40)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from PyQt4.QtGui import *
>>> dir(QDialog)
[..., 'colorCount', 'connect', 'connectNotify', 'contentsMargins', ...]
The connect
method is present in PyQt4:
Python 2.7.8 (default, Aug 24 2014, 21:26:19)
[GCC 4.2.1 Compatible Apple LLVM 5.1 (clang-503.0.40)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from PyQt4.QtGui import *
>>> dir(QDialog)
['Accepted', 'DialogCode', 'DrawChildren', 'DrawWindowBackground',
'IgnoreMask', 'PaintDeviceMetric', 'PdmDepth', 'PdmDpiX', 'PdmDpiY',
'PdmHeight', 'PdmHeightMM', 'PdmNumColors', 'PdmPhysicalDpiX',
'PdmPhysicalDpiY', 'PdmWidth', 'PdmWidthMM', 'Rejected', 'RenderFlag',
'RenderFlags', '__class__', '__delattr__', '__dict__', '__doc__',
'__format__', '__getattr__', '__getattribute__', '__hash__', '__init__',
'__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__',
'__setattr__', '__sizeof__', '__str__', '__subclasshook__',
'__weakref__', 'accept', 'acceptDrops', 'accepted',
'accessibleDescription', 'accessibleName', 'actionEvent', 'actions',
'activateWindow', 'addAction', 'addActions', 'adjustSize',
'autoFillBackground', 'backgroundRole', 'baseSize', 'blockSignals',
'changeEvent', 'childAt', 'childEvent', 'children', 'childrenRect',
'childrenRegion', 'clearFocus', 'clearMask', 'close', 'closeEvent',
'colorCount', 'connect', 'connectNotify', 'contentsMargins',
'contentsRect', 'contextMenuEvent', 'contextMenuPolicy', 'create',
'cursor', 'customContextMenuRequested', 'customEvent', 'deleteLater',
'depth', 'destroy', 'destroyed', 'devType', 'disconnect',
'disconnectNotify', 'done', 'dragEnterEvent', 'dragLeaveEvent',
'dragMoveEvent', 'dropEvent', 'dumpObjectInfo', 'dumpObjectTree',
'dynamicPropertyNames', 'effectiveWinId', 'emit', 'enabledChange',
'ensurePolished', 'enterEvent', 'event', 'eventFilter', 'exec_',
'extension', 'find', 'findChild', 'findChildren', 'finished',
'focusInEvent', 'focusNextChild', 'focusNextPrevChild', 'focusOutEvent',
'focusPolicy', 'focusPreviousChild', 'focusProxy', 'focusWidget',
'font', 'fontChange', 'fontInfo', 'fontMetrics', 'foregroundRole',
'frameGeometry', 'frameSize', 'geometry', 'getContentsMargins',
'grabGesture', 'grabKeyboard', 'grabMouse', 'grabShortcut',
'graphicsEffect', 'graphicsProxyWidget', 'handle', 'hasFocus',
'hasMouseTracking', 'height', 'heightForWidth', 'heightMM', 'hide',
'hideEvent', 'inherits', 'inputContext', 'inputMethodEvent',
'inputMethodHints', 'inputMethodQuery', 'insertAction', 'insertActions',
'installEventFilter', 'isActiveWindow', 'isAncestorOf', 'isEnabled',
'isEnabledTo', 'isEnabledToTLW', 'isFullScreen', 'isHidden',
'isLeftToRight', 'isMaximized', 'isMinimized', 'isModal',
'isRightToLeft', 'isSizeGripEnabled', 'isTopLevel', 'isVisible',
'isVisibleTo', 'isWidgetType', 'isWindow', 'isWindowModified',
'keyPressEvent', 'keyReleaseEvent', 'keyboardGrabber', 'killTimer',
'languageChange', 'layout', 'layoutDirection', 'leaveEvent', 'locale',
'logicalDpiX', 'logicalDpiY', 'lower', 'mapFrom', 'mapFromGlobal',
'mapFromParent', 'mapTo', 'mapToGlobal', 'mapToParent', 'mask',
'maximumHeight', 'maximumSize', 'maximumWidth', 'metaObject', 'metric',
'minimumHeight', 'minimumSize', 'minimumSizeHint', 'minimumWidth',
'mouseDoubleClickEvent', 'mouseGrabber', 'mouseMoveEvent',
'mousePressEvent', 'mouseReleaseEvent', 'move', 'moveEvent',
'moveToThread', 'nativeParentWidget', 'nextInFocusChain',
'normalGeometry', 'numColors', 'objectName', 'open', 'orientation',
'overrideWindowFlags', 'overrideWindowState', 'paintEngine',
'paintEvent', 'paintingActive', 'palette', 'paletteChange', 'parent',
'parentWidget', 'physicalDpiX', 'physicalDpiY', 'pos',
'previousInFocusChain', 'property', 'pyqtConfigure', 'raise_',
'receivers', 'rect', 'reject', 'rejected', 'releaseKeyboard',
'releaseMouse', 'releaseShortcut', 'removeAction', 'removeEventFilter',
'render', 'repaint', 'resetInputContext', 'resize', 'resizeEvent',
'restoreGeometry', 'result', 'saveGeometry', 'scroll', 'sender',
'senderSignalIndex', 'setAcceptDrops', 'setAccessibleDescription',
'setAccessibleName', 'setAttribute', 'setAutoFillBackground',
'setBackgroundRole', 'setBaseSize', 'setContentsMargins',
'setContextMenuPolicy', 'setCursor', 'setDisabled', 'setEnabled',
'setExtension', 'setFixedHeight', 'setFixedSize', 'setFixedWidth',
'setFocus', 'setFocusPolicy', 'setFocusProxy', 'setFont',
'setForegroundRole', 'setGeometry', 'setGraphicsEffect', 'setHidden',
'setInputContext', 'setInputMethodHints', 'setLayout',
'setLayoutDirection', 'setLocale', 'setMask', 'setMaximumHeight',
'setMaximumSize', 'setMaximumWidth', 'setMinimumHeight',
'setMinimumSize', 'setMinimumWidth', 'setModal', 'setMouseTracking',
'setObjectName', 'setOrientation', 'setPalette', 'setParent',
'setProperty', 'setResult', 'setShortcutAutoRepeat',
'setShortcutEnabled', 'setShown', 'setSizeGripEnabled',
'setSizeIncrement', 'setSizePolicy', 'setStatusTip', 'setStyle',
'setStyleSheet', 'setTabOrder', 'setToolTip', 'setUpdatesEnabled',
'setVisible', 'setWhatsThis', 'setWindowFilePath', 'setWindowFlags',
'setWindowIcon', 'setWindowIconText', 'setWindowModality',
'setWindowModified', 'setWindowOpacity', 'setWindowRole',
'setWindowState', 'setWindowTitle', 'show', 'showEvent',
'showExtension', 'showFullScreen', 'showMaximized', 'showMinimized',
'showNormal', 'signalsBlocked', 'size', 'sizeHint', 'sizeIncrement',
'sizePolicy', 'stackUnder', 'startTimer', 'staticMetaObject',
'statusTip', 'style', 'styleSheet', 'tabletEvent', 'testAttribute',
'thread', 'timerEvent', 'toolTip', 'topLevelWidget', 'tr', 'trUtf8',
'underMouse', 'ungrabGesture', 'unsetCursor', 'unsetLayoutDirection',
'unsetLocale', 'update', 'updateGeometry', 'updateMicroFocus',
'updatesEnabled', 'visibleRegion', 'whatsThis', 'wheelEvent', 'width',
'widthMM', 'winId', 'window', 'windowActivationChange',
'windowFilePath', 'windowFlags', 'windowIcon', 'windowIconText',
'windowModality', 'windowOpacity', 'windowRole', 'windowState',
'windowTitle', 'windowType', 'x', 'y']
But not PyQt5:
Python 3.4.1 (default, Aug 24 2014, 21:32:40)
[GCC 4.2.1 Compatible Apple LLVM 5.1 (clang-503.0.40)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from PyQt5.QtWidgets import *
>>> dir(QDialog)
['Accepted', 'DialogCode', 'DrawChildren', 'DrawWindowBackground',
'IgnoreMask', 'PaintDeviceMetric', 'PdmDepth', 'PdmDevicePixelRatio',
'PdmDpiX', 'PdmDpiY', 'PdmHeight', 'PdmHeightMM', 'PdmNumColors',
'PdmPhysicalDpiX', 'PdmPhysicalDpiY', 'PdmWidth', 'PdmWidthMM',
'Rejected', 'RenderFlag', 'RenderFlags', '__class__', '__delattr__',
'__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__',
'__getattr__', '__getattribute__', '__gt__', '__hash__', '__init__',
'__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__',
'__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__',
'__subclasshook__', '__weakref__', 'accept', 'acceptDrops', 'accepted',
'accessibleDescription', 'accessibleName', 'actionEvent', 'actions',
'activateWindow', 'addAction', 'addActions', 'adjustSize',
'autoFillBackground', 'backgroundRole', 'baseSize', 'blockSignals',
'changeEvent', 'childAt', 'childEvent', 'children', 'childrenRect',
'childrenRegion', 'clearFocus', 'clearMask', 'close', 'closeEvent',
'colorCount', 'connectNotify', 'contentsMargins', 'contentsRect',
'contextMenuEvent', 'contextMenuPolicy', 'create',
'createWindowContainer', 'cursor', 'customContextMenuRequested',
'customEvent', 'deleteLater', 'depth', 'destroy', 'destroyed',
'devType', 'devicePixelRatio', 'disconnect', 'disconnectNotify', 'done',
'dragEnterEvent', 'dragLeaveEvent', 'dragMoveEvent', 'dropEvent',
'dumpObjectInfo', 'dumpObjectTree', 'dynamicPropertyNames',
'effectiveWinId', 'ensurePolished', 'enterEvent', 'event',
'eventFilter', 'exec', 'exec_', 'find', 'findChild', 'findChildren',
'finished', 'focusInEvent', 'focusNextChild', 'focusNextPrevChild',
'focusOutEvent', 'focusPolicy', 'focusPreviousChild', 'focusProxy',
'focusWidget', 'font', 'fontInfo', 'fontMetrics', 'foregroundRole',
'frameGeometry', 'frameSize', 'geometry', 'getContentsMargins', 'grab',
'grabGesture', 'grabKeyboard', 'grabMouse', 'grabShortcut',
'graphicsEffect', 'graphicsProxyWidget', 'hasFocus',
'hasHeightForWidth', 'hasMouseTracking', 'height', 'heightForWidth',
'heightMM', 'hide', 'hideEvent', 'inherits', 'initPainter',
'inputMethodEvent', 'inputMethodHints', 'inputMethodQuery',
'insertAction', 'insertActions', 'installEventFilter', 'isActiveWindow',
'isAncestorOf', 'isEnabled', 'isEnabledTo', 'isFullScreen', 'isHidden',
'isLeftToRight', 'isMaximized', 'isMinimized', 'isModal',
'isRightToLeft', 'isSignalConnected', 'isSizeGripEnabled', 'isVisible',
'isVisibleTo', 'isWidgetType', 'isWindow', 'isWindowModified',
'isWindowType', 'keyPressEvent', 'keyReleaseEvent', 'keyboardGrabber',
'killTimer', 'layout', 'layoutDirection', 'leaveEvent', 'locale',
'logicalDpiX', 'logicalDpiY', 'lower', 'mapFrom', 'mapFromGlobal',
'mapFromParent', 'mapTo', 'mapToGlobal', 'mapToParent', 'mask',
'maximumHeight', 'maximumSize', 'maximumWidth', 'metaObject', 'metric',
'minimumHeight', 'minimumSize', 'minimumSizeHint', 'minimumWidth',
'mouseDoubleClickEvent', 'mouseGrabber', 'mouseMoveEvent',
'mousePressEvent', 'mouseReleaseEvent', 'move', 'moveEvent',
'moveToThread', 'nativeEvent', 'nativeParentWidget', 'nextInFocusChain',
'normalGeometry', 'objectName', 'objectNameChanged', 'open',
'overrideWindowFlags', 'overrideWindowState', 'paintEngine',
'paintEvent', 'paintingActive', 'palette', 'parent', 'parentWidget',
'physicalDpiX', 'physicalDpiY', 'pos', 'previousInFocusChain',
'property', 'pyqtConfigure', 'raise_', 'receivers', 'rect',
'redirected', 'reject', 'rejected', 'releaseKeyboard', 'releaseMouse',
'releaseShortcut', 'removeAction', 'removeEventFilter', 'render',
'repaint', 'resize', 'resizeEvent', 'restoreGeometry', 'result',
'saveGeometry', 'scroll', 'sender', 'senderSignalIndex',
'setAcceptDrops', 'setAccessibleDescription', 'setAccessibleName',
'setAttribute', 'setAutoFillBackground', 'setBackgroundRole',
'setBaseSize', 'setContentsMargins', 'setContextMenuPolicy',
'setCursor', 'setDisabled', 'setEnabled', 'setFixedHeight',
'setFixedSize', 'setFixedWidth', 'setFocus', 'setFocusPolicy',
'setFocusProxy', 'setFont', 'setForegroundRole', 'setGeometry',
'setGraphicsEffect', 'setHidden', 'setInputMethodHints', 'setLayout',
'setLayoutDirection', 'setLocale', 'setMask', 'setMaximumHeight',
'setMaximumSize', 'setMaximumWidth', 'setMinimumHeight',
'setMinimumSize', 'setMinimumWidth', 'setModal', 'setMouseTracking',
'setObjectName', 'setPalette', 'setParent', 'setProperty', 'setResult',
'setShortcutAutoRepeat', 'setShortcutEnabled', 'setSizeGripEnabled',
'setSizeIncrement', 'setSizePolicy', 'setStatusTip', 'setStyle',
'setStyleSheet', 'setTabOrder', 'setToolTip', 'setToolTipDuration',
'setUpdatesEnabled', 'setVisible', 'setWhatsThis', 'setWindowFilePath',
'setWindowFlags', 'setWindowIcon', 'setWindowIconText',
'setWindowModality', 'setWindowModified', 'setWindowOpacity',
'setWindowRole', 'setWindowState', 'setWindowTitle', 'sharedPainter',
'show', 'showEvent', 'showFullScreen', 'showMaximized', 'showMinimized',
'showNormal', 'signalsBlocked', 'size', 'sizeHint', 'sizeIncrement',
'sizePolicy', 'stackUnder', 'startTimer', 'staticMetaObject',
'statusTip', 'style', 'styleSheet', 'tabletEvent', 'testAttribute',
'thread', 'timerEvent', 'toolTip', 'toolTipDuration', 'tr',
'underMouse', 'ungrabGesture', 'unsetCursor', 'unsetLayoutDirection',
'unsetLocale', 'update', 'updateGeometry', 'updateMicroFocus',
'updatesEnabled', 'visibleRegion', 'whatsThis', 'wheelEvent', 'width',
'widthMM', 'winId', 'window', 'windowFilePath', 'windowFlags',
'windowHandle', 'windowIcon', 'windowIconChanged', 'windowIconText',
'windowIconTextChanged', 'windowModality', 'windowOpacity',
'windowRole', 'windowState', 'windowTitle', 'windowTitleChanged',
'windowType', 'x', 'y']
What am I missing?
You are using old-style signals and slots which have not been implemented in PyQt5. Try using new-style signals and slots.
self.lineedit.returnPressed.connect(self.updateUi)
Another answer is to add keyPressEvent() method to capture keyboards events.
It will call your updateUi() method when the correct key is pressed.
def keyPressEvent(self, event):
key = event.key()
if key == Qt.Key_Enter:
#For Enter of keyboard number
print("key Enter press")
self.updateUi()
if key == Qt.Key_Return:
#For Enter of keyboard
print("key Enter press")
self.updateUi()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With