• 2617阅读
  • 9回复

解决第4章例子“30行的表达式求值”对PyQt5+Python3兼容性的问题。 [复制链接]

上一主题 下一主题
离线wps2000
 

只看楼主 倒序阅读 楼主  发表于: 2016-10-11
原来书中的代码是这样的:


from __future__ import division
import sys
from math import *
from PyQt4.QtCore import *
from PyQt4.QtGui 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()
        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_()

第一,对于PyQt5来说,还是老问题,要把from PyQt5.QtWidgets import *加进去。

第二,类Form,是QDialog的子类,在Form类中,
self.connect(self.lineedit, SIGNAL("returnPressed()"),
                     self.updateUi)

里面的connect在 PyQt5中已经取消。如果运行的话,会出现:AttributeError: 'Form' object has no attribute 'connect',这个错误。要改成:

self.lineedit.returnPressed.connect(self.updateUi)

因此,完整的代码为:


from __future__ import division
import sys
from math import *
from PyQt5.QtCore import *
from PyQt5.QtGui 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()
        self.lineedit.returnPressed.connect(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_()

但最后一个问题,始终没解决。那就是对话框出来之后,输入数学表达式,对话框就自动消失了。换成PyQt4也很扯,虽然没消失,但对话框没任何反应。请高手指教。
离线wps2000

只看该作者 1楼 发表于: 2016-10-11
解决了。继续更新。问题就出在text = unicode(self.lineedit.text())
这个地方。因为我安装的是python3.5,python3以上版本,默认都是unicode,所以把unicode去掉就OK了。pyqt5 + phython3的完整代码:

from __future__ import division
import sys
from math import *
from PyQt5.QtCore import *
from PyQt5.QtGui 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()
        #self.connect(self.lineedit, SIGNAL("returnPressed()"),
        #             self.updateUi)
        self.lineedit.returnPressed.connect(self.updateUi)
        self.setWindowTitle("Calculate")


    def updateUi(self):
        try:
            text = 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_()
离线suandefujian

只看该作者 2楼 发表于: 2016-12-10
谢谢。
离线meik

只看该作者 3楼 发表于: 2016-12-11
多谢楼主 就是这个问题卡了我一整天

本条消息发送于


离线linote

只看该作者 4楼 发表于: 2017-04-19
谢谢
离线dz4543

只看该作者 5楼 发表于: 2017-09-11
谢谢
离线wy680000

只看该作者 6楼 发表于: 2018-06-10
请问下PyCharm 2018.1.3怎么自动补齐PyQt中控件的方法
离线mali78120

只看该作者 7楼 发表于: 2018-11-08
好文,赞一个!
离线飞来石

只看该作者 8楼 发表于: 2018-12-29
真是好帖子,有收获,谢谢!
离线飞来石

只看该作者 9楼 发表于: 2018-12-29
def __init__(self, parent=None):
        super(Form, self).__init__(parent)

为了查明 super() 方法的背后逻辑,以及书中所说 将 parent 设为 None 的意义,即 代表 Form类是顶级窗口,“因为脱离了父系”。但是试验结果发现 Form类的父类 QDialog 实质上还是起作用的。将上面的两句改成以下两种构造方法的都可以运行:

def __init__(self):
        super(Form, self).__init__()

def __init__(self):
        QDialog.__init__(self)

经过查询 python help文件,以及受到网上帖子的启发,可以最终确定,super () 方法的作用就是将类的 “父系” 变为隐式的,便于代码的移植。而程序中的 parent = None,估计并无实际作用,只是相当于注释的含义。
快速回复
限100 字节
 
上一个 下一个