理解 pyqt 中的 connectSlotsByName() 时遇到问题?
我无法理解 pyuic4 主要使用的 connectSlotsByName() 方法。到目前为止,该类在 PyQt 文件中是单个类,这是可以的,因为我们可以使用 self ,它将始终与单个对象关联。但是当我们尝试时要使用不同文件中的各种类,就会出现问题并需要使用 connectSlotsByName() .. 这是我遇到的奇怪的情况..
我创建了一个堆叠的小部件..
我在上面放置了我的第一个小部件.. 它 有一个名为“下一步>”的按钮。
单击“下一步”时,它会隐藏当前的 小部件并添加另一个具有“单击我”按钮的小部件。
这里的问题是第二个“单击我”按钮的单击事件未捕获。这是我可以为我的原始问题提供的一个最小示例。请帮助我..
这是文件No.1..(其中有父级堆叠小部件及其第一页)。单击“下一步”时,它会添加第二个页面,该页面在 file2 中具有“clickme”按钮。
from PyQt4 import QtCore, QtGui
import file2
class Ui_StackedWidget(QtGui.QStackedWidget):
def __init__(self,parent=None):
QtGui.QStackedWidget.__init__(self,parent)
self.setObjectName("self")
self.resize(484, 370)
self.setWindowTitle(QtGui.QApplication.translate("self", "stacked widget", None, QtGui.QApplication.UnicodeUTF8))
self.createWidget1()
def createWidget1(self):
self.page=QtGui.QWidget()
self.page.setObjectName("widget1")
self.pushButton=QtGui.QPushButton(self.page)
self.pushButton.setGeometry(QtCore.QRect(150, 230, 91, 31))
self.pushButton.setText(QtGui.QApplication.translate("self", "Next >", None, QtGui.QApplication.UnicodeUTF8))
self.addWidget(self.page)
QtCore.QMetaObject.connectSlotsByName(self.page)
QtCore.QObject.connect(self.pushButton,QtCore.SIGNAL('clicked()'),self.showWidget2)
def showWidget2(self):
self.page.hide()
obj=file2.widget2()
obj.createWidget2(self)
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
ui = Ui_StackedWidget()
ui.show()
sys.exit(app.exec_())
这是 file2
from PyQt4 import QtGui,QtCore
class widget2():
def createWidget2(self,parent):
self.page = QtGui.QWidget()
self.page.setObjectName("page")
self.parent=parent
self.groupBox = QtGui.QGroupBox(self.page)
self.groupBox.setGeometry(QtCore.QRect(30, 20, 421, 311))
self.groupBox.setObjectName("groupBox")
self.groupBox.setTitle(QtGui.QApplication.translate("self", "TestGroupBox", None, QtGui.QApplication.UnicodeUTF8))
self.pushButton = QtGui.QPushButton(self.groupBox)
self.pushButton.setGeometry(QtCore.QRect(150, 120, 92, 28))
self.pushButton.setObjectName("pushButton")
self.pushButton.setText(QtGui.QApplication.translate("self", "Click Me", None, QtGui.QApplication.UnicodeUTF8))
self.parent.addWidget(self.page)
self.parent.setCurrentWidget(self.page)
QtCore.QMetaObject.connectSlotsByName(self.page)
QtCore.QObject.connect(self.pushButton,QtCore.SIGNAL('clicked()'),self.printMessage)
def printMessage(self):
print("Hai")
虽然在两个小部件(我的意思是页面)中,
QtCore.QMetaObject.connectSlotsByName(self.page)
第二个对话框中的单击信号未得到处理。预先感谢..可能是一个初学者的问题..
I couldn't understand the connectSlotsByName() method which is predominently used by pyuic4.. As far the class is single in a PyQt file it's ok since we can use self which will be associated with a single object throughout.. But when we try to use various classes from different files the problem and the need to use connectSlotsByName() arises.. Here's what i encountered which is weird..
I created a stacked widget..
I placed my first widget on it.. It
has a button called "Next >".On clicking next it hides the current
widget and adds another widget which has the "click me" button..
The problem here is the click event for "click me" button in second is not captured.. It's a minimal example that i can give for my original problem.. Please help me..
This is file No.1..(which has the parent stacked widget and it's first page). On clicking next it adds the second page which has "clickme" button in file2..
from PyQt4 import QtCore, QtGui
import file2
class Ui_StackedWidget(QtGui.QStackedWidget):
def __init__(self,parent=None):
QtGui.QStackedWidget.__init__(self,parent)
self.setObjectName("self")
self.resize(484, 370)
self.setWindowTitle(QtGui.QApplication.translate("self", "stacked widget", None, QtGui.QApplication.UnicodeUTF8))
self.createWidget1()
def createWidget1(self):
self.page=QtGui.QWidget()
self.page.setObjectName("widget1")
self.pushButton=QtGui.QPushButton(self.page)
self.pushButton.setGeometry(QtCore.QRect(150, 230, 91, 31))
self.pushButton.setText(QtGui.QApplication.translate("self", "Next >", None, QtGui.QApplication.UnicodeUTF8))
self.addWidget(self.page)
QtCore.QMetaObject.connectSlotsByName(self.page)
QtCore.QObject.connect(self.pushButton,QtCore.SIGNAL('clicked()'),self.showWidget2)
def showWidget2(self):
self.page.hide()
obj=file2.widget2()
obj.createWidget2(self)
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
ui = Ui_StackedWidget()
ui.show()
sys.exit(app.exec_())
Here's file2
from PyQt4 import QtGui,QtCore
class widget2():
def createWidget2(self,parent):
self.page = QtGui.QWidget()
self.page.setObjectName("page")
self.parent=parent
self.groupBox = QtGui.QGroupBox(self.page)
self.groupBox.setGeometry(QtCore.QRect(30, 20, 421, 311))
self.groupBox.setObjectName("groupBox")
self.groupBox.setTitle(QtGui.QApplication.translate("self", "TestGroupBox", None, QtGui.QApplication.UnicodeUTF8))
self.pushButton = QtGui.QPushButton(self.groupBox)
self.pushButton.setGeometry(QtCore.QRect(150, 120, 92, 28))
self.pushButton.setObjectName("pushButton")
self.pushButton.setText(QtGui.QApplication.translate("self", "Click Me", None, QtGui.QApplication.UnicodeUTF8))
self.parent.addWidget(self.page)
self.parent.setCurrentWidget(self.page)
QtCore.QMetaObject.connectSlotsByName(self.page)
QtCore.QObject.connect(self.pushButton,QtCore.SIGNAL('clicked()'),self.printMessage)
def printMessage(self):
print("Hai")
Though in both the widgets(i mean pages)
QtCore.QMetaObject.connectSlotsByName(self.page)
the clicked signal in second dialog isn't getting processed. Thanks in advance.. Might be a beginner question..
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
首先,这是一个最小的工作示例:
当您尝试按名称连接插槽时,您必须为插槽提供正确的名称,然后某人(moc、uic 或您通过调用 connectSlotsByName)必须连接它们。此类插槽的正确名称是:“on_PyQtObjectName_PyQtSignalName”。
请注意,如果我在示例中省略了 @QtCore.pyqtSlot(),则每个适当的重载都会执行一次 slot (在本例中为两次)。
您确实需要直接调用 connectSlotsByNames,因为没有 moc,当您在 C++ 中使用 QT 时,它会为您完成此操作,并且您不使用 uic 和 .ui 文件。如果你想隐式连接插槽(我总是这样做,除了在.ui中直接连接的插槽),你最好使用更多的pytonish语法:button.clicked.connect(self._mySlot)。
并查看 https://riverbankcomputing.com /static/Docs/PyQt5/signals_slots.html#connecting-slots-by-name
At first, here is the minimal working example:
When you trying to connect slots by name, you must give proper names to the slots and then someone (moc, uic, or you by calling connectSlotsByName) must connect them. Proper name for such a slot is: "on_PyQtObjectName_PyQtSignalName".
Note, that, if I'd omitted @QtCore.pyqtSlot() in the example, slot would be executed once for every appropriate overload (twice in this case).
You DO need to call connectSlotsByNames directly, cause there is no moc, which do it for you when you use QT in C++, and you do not use uic and .ui file. If you want to connect slots implicitly (I'm always doing so, except slots, connected directly in .ui), you'd better use more pytonish syntaxe: button.clicked.connect(self._mySlot).
And take a look at https://riverbankcomputing.com/static/Docs/PyQt5/signals_slots.html#connecting-slots-by-name
更好的问题是“为什么不直接使用新型信号和槽?”。它们要简单得多,不需要任何奇怪的命名约定:
A better question is "Why not just use new-style signals and slots?". They're much simpler and don't require any weird naming conventions:
您不需要调用 connectSlotsByName(),只需删除这些行即可。
在
file2
中,调用QtCore.QMetaObject.connectSlotsByName(self.page)
尝试执行此操作:自
self.on_pushBotton_clicked()
起,这对您不起作用code> 槽未定义。我发现在 PyQt 中创建您自己的连接是最简单的...我建议从您的两个类中删除对
connectSlotsByName
的调用...您不需要它。另外,您的
wdiget1
类应设置其 pushButton 的名称(最好是“pushButton”以外的名称,以避免与widget2
中的按钮混淆)。You do not need to call
connectSlotsByName()
, just remove those lines.In
file2
, callingQtCore.QMetaObject.connectSlotsByName(self.page)
tries to do this:That will not work for you since
self.on_pushBotton_clicked()
slot is not defined.I find it is easiest to create your own connections in PyQt... I recommend removing the calls to
connectSlotsByName
from your both classes... you do not need it.Also, your
wdiget1
class should set the name of it's pushButton (preferably something other then "pushButton" to avoid confusion with the button inwidget2
).非常感谢jcoon的回复..但是经过很长一段时间,我把头撞在墙上,我找到了解决方案..
问题是..
而不是obj..
Thank you so much jcoon for your reply.. But after a very long time banging my head against the wall i found the solution..
The problem was..
instead of obj..
这是@MarkVisser 的 QT4 代码更新为 QT5:
Here is @MarkVisser's QT4 code updated to QT5:
另一个使用Qt for Python的最小工作示例,又名PySide2/6。
关键要素:
.setObjectName
@QtCore.Slot()
装饰self
)我真的无法让它变得更小
Another minimal working example with Qt for Python aka PySide2/6.
Key ingredients:
.setObjectName
@QtCore.Slot()
self
here)I couldn't get mit any smaller really ????