查看完整版本: [-- 解决第4章例子“30行的表达式求值”对PyQt5+Python3兼容性的问题。 --]

QTCN开发网 -> Python Qt GUI快速编程 -> 解决第4章例子“30行的表达式求值”对PyQt5+Python3兼容性的问题。 [打印本页] 登录 -> 注册 -> 回复主题 -> 发表主题

wps2000 2016-10-11 13:35

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

原来书中的代码是这样的:


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 2016-10-11 15:36
解决了。继续更新。问题就出在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 2016-12-10 14:22
谢谢。

meik 2016-12-11 13:35
多谢楼主 就是这个问题卡了我一整天

本条消息发送于



linote 2017-04-19 23:01
谢谢

dz4543 2017-09-11 21:08
谢谢

wy680000 2018-06-10 17:15
请问下PyCharm 2018.1.3怎么自动补齐PyQt中控件的方法

mali78120 2018-11-08 19:50
好文,赞一个!

飞来石 2018-12-29 20:44
真是好帖子,有收获,谢谢!

飞来石 2018-12-29 23:02
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,估计并无实际作用,只是相当于注释的含义。

mhy3477 2022-03-03 17:21
我的按照你这样改, 貌似还是不行哦:
如下提示:
self.lineedit.returnPressed.connect(self.updateUi)
AttributeError: 'Form' object has no attribute 'updateUi'

mhy3477 2022-03-08 18:59
没有人回复吗?


查看完整版本: [-- 解决第4章例子“30行的表达式求值”对PyQt5+Python3兼容性的问题。 --] [-- top --]



Powered by phpwind v8.7 Code ©2003-2011 phpwind
Gzip disabled