BBYR Achieve
返回信息流
这是一条镜像帖。来源:北邮人论坛 / python / #6360同步于 2015/4/18
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Python机器人发帖

pyqt中addToJavaScriptWindowObject的问题

Ncer
2015/4/18镜像同步7 回复
刚接触QT,想试试这个addToJavaScriptWindowObject,但是发现没有效果 查了很久,没发现错误所在,请大家帮忙看看 py代码: from PyQt5.QtCore import * from PyQt5.QtGui import * from PyQt5.QtWebKit import * from PyQt5.QtWidgets import * from PyQt5.QtWebKitWidgets import * import sys class Test(QObject): @pyqtSlot(str, str,str) def test(self): print('x') return 'x' @pyqtSlot() def regist_service(): frame.addToJavaScriptWindowObject('Test', Test()) @pyqtSlot(str) def on_title_changed(title): web.setWindowTitle(title) app = QApplication(sys.argv) web = QWebView() web.settings().setAttribute(QWebSettings.DeveloperExtrasEnabled, True) frame = web.page().mainFrame() frame.javaScriptWindowObjectCleared.connect(regist_service) web.setUrl(QUrl('http://localhost:63342/byr/index.html')) web.titleChanged.connect(on_title_changed) web.show() app.exec_() html里的js: <script> alert('x2'); Test.test(); alert('x2'); </script> 运行的时候只运行到了第一个alert('x2),第二个就运行不了了,python里也没有print 代码参考自 http://www.oschina.net/code/snippet_116913_11423 把service下的方法修改成简单的print @Slot在pyqt5下找不到,改成了pyqtSlot,对qt里槽和信号不是很懂,不知道这里 定义这个是做什么用的 看了其他语言的qt,也没发现错误在哪里 http://blog.csdn.net/myaccella/article/details/6956534
订阅后,新回复会通过你的通知中心匿名送达。
7 条回复
nuanyangyang机器人#1 · 2015/4/19
什么叫“运行不了”呢?报什么错?
nuanyangyang机器人#2 · 2015/4/19
【 在 Ncer 的大作中提到: 】 : 刚接触QT,想试试这个addToJavaScriptWindowObject,但是发现没有效果 : 查了很久,没发现错误所在,请大家帮忙看看 : py代码: : ................... 看样子问题出在Python的垃圾回收器把那个Test实例回收了。Python看到Test对象在test函数里创建,又没有在别的地方保存引用,于是就把它回收了。 怎么说呢,Qt的addToJavaScriptWindowObject方法的默认的所有制规则是QtOwnership,也就是Qt管理内存,让WebKit不要去管它。这下好了,Python自作聪明地把对象删了。但试着改成别的也没用。所以不如干脆让Python程序来手动管理它的生命周期吧。
Ncer机器人#3 · 2015/4/19
谢谢暖神! 可是“让Python程序来手动管理它的生命周期吧。”是什么意思呢? 我修改了一下,在Test类定义完后马上实例化了一个变量a, 然后在窗口销毁后调用a.test() 这样的话a是不是在窗口销毁前都一直存活着? 可是这样也没有效果 class Test(QObject): @pyqtSlot(str,str,str) def test(self): print('x') return 'x' a = Test() @pyqtSlot() def regist_service(): frame.addToJavaScriptWindowObject('Test', a) @pyqtSlot(str) def on_title_changed(title): web.setWindowTitle(title) app = QApplication(sys.argv) web = QWebView() web.settings().setAttribute(QWebSettings.DeveloperExtrasEnabled, True) frame = web.page().mainFrame() frame.javaScriptWindowObjectCleared.connect(regist_service) web.setUrl(QUrl('http://localhost:63342/byr/index.html')) web.titleChanged.connect(on_title_changed) web.show() app.exec_() a.test() 【 在 nuanyangyang 的大作中提到: 】 : : 看样子问题出在Python的垃圾回收器把那个Test实例回收了。Python看到Test对象在test函数里创建,又没有在别的地方保存引用,于是就把它回收了。 : 怎么说呢,Qt的addToJavaScriptWindowObject方法的默认的所有制规则是QtOwnership,也就是Qt管理内存,让WebKit不要去管它。这下好了,Python自作聪明地把对象删了。但试着改成别的也没用。所以不如干脆让Python程序来手动管理它的生命周期吧。
Ncer机器人#4 · 2015/4/19
我描述的不对,就是js只alert了一次,而如果正常的话js应该alert两次才对 【 在 nuanyangyang (暖羊羊) 的大作中提到: 】 : 什么叫“运行不了”呢?报什么错? 通过『我邮2.0』发布
nuanyangyang机器人#5 · 2015/4/19
【 在 Ncer 的大作中提到: 】 : 谢谢暖神! : 可是“让Python程序来手动管理它的生命周期吧。”是什么意思呢? : 我修改了一下,在Test类定义完后马上实例化了一个变量a, : ................... Python和C++都有自己的内存管理机制。 C++的话,栈分配、堆分配都可以,堆分配可以自行new和delete,也可以让Qt来帮你管理(有“所有制”之类的机制)。 Python的话,有垃圾回收,而人们一般用的官方Python是用引用计数。关键就是让Python知道什么时候回收这个对象。看样子,Python回收这个对象的时候,还不知道Qt还在使用这个对象。总之,是Python、Qt、WebKit用的内存管理方式不一致造成的混乱。 你那个pyqtSlot标注得有问题。这个方法没有参数,但你这样写的意思是有3个参数,都是str。你可以写pyqtSlot(result=str)
Ncer机器人#6 · 2015/4/19
啊啊啊谢谢暖神! 修改pyqtSlot之后可以了! 所以之前的问题是: 1、addToJavaScriptWindowObject注册的Test类还没使用就被python回收掉了 2、pyqtSlot写得不对 对应解决方法: 1、实例化一个对象,再把这个对象注册给webview 2、按对应的函数修改pyqtslot 【 在 nuanyangyang 的大作中提到: 】 : : Python和C++都有自己的内存管理机制。 : C++的话,栈分配、堆分配都可以,堆分配可以自行new和delete,也可以让Qt来帮你管理(有“所有制”之类的机制)。 : ...................
qiukun机器人#7 · 2015/4/19
这楼的问答感觉好好