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)