使用子目录时PyQt4的SIGNAL/SLOT问题
感谢你花时间来阅读这个内容。抱歉有点啰嗦,但希望能完全解释清楚问题。下面有一些简化的代码示例来展示这个问题。
我在使用 PyQt4 的信号和槽时遇到了一些问题。当我在一个文件中写代码时,一切都能正常工作,但如果我把一些想用的函数移动到子目录或类中,就无法正常工作了。
我查看了Python 绑定文档,我明白了在单个文件中是怎么工作的。但我想做的是这样的:
- 在根目录下有一个 main.py 文件,里面包含 MainWindow 的
__init__
代码。 - 这个文件导入了多个小部件。每个小部件都存放在自己的子目录中。所有子目录里都有一个
__init__.py
文件。这些子目录在一个叫 'bin' 的目录下,而这个 'bin' 目录又在根目录里。 - 这些小部件之间需要有信号和槽的连接,这就是我遇到问题的地方。
所以文件结构是:
- main.py
- bin/textEditor/__init__.py
- bin/textEditor/plugin.py
- bin/logWindow/__init__.py
- bin/logWindow/plugin.py
以下代码展示了问题。这段代码创建了一个非常基本的主窗口,里面有一个中央的 QTextEdit()
小部件和一个可停靠的 QTextEdit()
小部件。发生的事情是,当中央小部件中的文本改变时,停靠的小部件中也会显示相同的文本。这个例子是可以工作的。但它是通过在 bin/textEditor/plugin.py
文件中连接中央 QTextEdit()
的信号 textChanged() 和 main.py
中的一个函数来实现的。我希望它能做同样的事情,但连接到 bin/textEditor/plugin.py
中的 updateUi 函数。
如果有人能对此提供一些帮助,我将非常感激。我相信这很简单。但如果能指引我找到相关的教程,或者告诉我我做错了什么,我也会很感激!再次感谢你的时间:
### main.py
import os
import sys
# Import PyQT modules
from PyQt4.QtCore import *
from PyQt4.QtGui import *
# Start the main class
class MainWindow(QMainWindow):
# Initialise
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
# Name and size the main window
self.setWindowTitle("EDITOR/LOG")
self.resize(800, 600)
import bin.logWindow.plugin as logWindow
logWindow.create(self)
import bin.textEditor.plugin as textEditor
textEditor.create(self)
def updateUi(self):
# I can connect to this function from within bin/textEditor/plugin.py (see
# below) but I want to connect to the function located in
# bin/textEditor/plugin.py instead
text = self.editor.toPlainText()
self.logWidget.setText(text)
# Run the app
def main():
app = QApplication(sys.argv)
form = MainWindow()
form.show()
app.exec_()
# Call main
main()
两个插件文件中的代码是:
### bin/textEditor/plugin.py
# Import PyQT modules
from PyQt4.QtCore import *
from PyQt4.QtGui import *
def create(self):
# Add a dockable widget
self.logDockWidget = QDockWidget("Log", self)
self.logDockWidget.setObjectName("LogDockWidget")
self.logDockWidget.setAllowedAreas(Qt.LeftDockWidgetArea|
Qt.RightDockWidgetArea)
self.logWidget = QTextEdit()
self.logDockWidget.setWidget(self.logWidget)
self.addDockWidget(Qt.LeftDockWidgetArea, self.logDockWidget)
还有
### bin/logWindow/plugin.py
Import PyQT modules
from PyQt4.QtCore import *
from PyQt4.QtGui import *
def create(self):
# Create a text editing box
self.editor = QTextEdit()
# Add to main window
self.setCentralWidget(self.editor)
# connect text change to update log window. This is presumably what I need to
# change so that it connects to the function below instead of the on in main.py
self.connect(self.editor, SIGNAL("textChanged()"), self.updateUi)
def updateUi(self):
text = self.editor.toPlainText()
self.logWidget.setText(text)
1 个回答
首先,你为什么还在用一个很旧的PyQt文档版本呢?新的版本在这里:这里
你做的一些事情有点不太寻常。一般来说,在Python中,导入语句通常放在文件的最上面(这样可以更容易看到依赖关系),不过我猜你这么做是为了将来支持更通用的插件导入系统。
看起来你面临的基本问题是,你试图把一个信号源连接到另一个对象中的一个槽,但没有把那个对象存储在特定的位置。要做到这一点,你可能需要在主程序中建立连接,或者创建一个中立的“updateUi”槽,这个槽会发出自己特有的信号,所有插件都在等待这个信号,或者干脆在主程序中保留对那些子对象的引用,并注意初始化的顺序。