如何在动态创建的QTabWidget页面中查看来自QWidgets的信号?

时间:2013-06-27 13:41:10

标签: python-3.x pyqt4 qwidget qt-designer qtabwidget

编辑:我提出了一个解决方案,它比我想象的要简单得多。原始代码和问题在顶部。我的解决方案在下面的“问题”之后。

示例

from PyQt4 import QtGui, QtCore
from example_Ui import Ui_MainWindow
from filler_Ui import Form


class TabFiller(Form):
    def __init__(self, parent=None):
        Form.__init__(self, parent)

    def TabButtonClicked(self):
        print("Tab button pressed.")

    def LineEditChanged(self):
        print("LineEdit contents edited in tab page!")


class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.setupUi(self)

    tab_filler = [] # create empty list for tab contents
    tab_page = [] # create empty list for tab page
    tab_count = 0

    def CreateNewTab(self):
        tab_title = "New Tab : " + str(self.tab_count)
        self.tab_filler.append(TabFiller())
        self.tab_filler[self.tab_count].label.setText(tab_title)
        self.tab_page.append(self.tab_filler[self.tab_count])
        self.tabWidget.addTab(self.tab_page[self.tab_count], tab_title)
        self.tab_count += 1

    def MainButtonPressed(self):
        self.CreateNewTab()

if __name__ == '__main__':
    import sys
    app = QtGui.QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())

MainWindow包含一个QTabWidget,它是一个Button。 clicked()信号已在QtDesigner中定义,以发送到MainWindow类内的MainButtonPressed()函数。

表单小部件也在QTdesigner中创建。用于填充其他标签页。 它包含一个Button小部件和一个LineEdit小部件。

问题

我无法理解 我可以告诉每个标签中点击或编辑了哪些小部件。

我知道每个标签页都存储在名为 tab_page 列表中。

在MainWindow类中,如何在当前活动的选项卡中收到给定窗口小部件的clicked()或finishedEditing()信号?

解决方案

import sys
from PyQt4.QtGui import *
from PyQt4.QtCore import *
from PyQt4 import QtGui
from example_Ui import Ui_MainWindow
from filler_Ui import Form

class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.setupUi(self)

    tab_index = 1 # 1 because we already made a default tab in QtDesigner

    def LineEditChanged(self):
        findWidget = self.tabWidget.widget(self.tabWidget.currentIndex()).findChildren(QtGui.QLineEdit, "lineEdit")
        if findWidget[0].isModified() == True:
            print("LineEdit contents edited in tab page!")
            print("Name of page edited :", "'", self.tabWidget.tabText(self.tabWidget.currentIndex()),"'")

    def TabButtonPressed(self):
        print("YOU DID IT!")
        print("Current Tab Index = ", self.tabWidget.currentIndex())

    def CreateNewTab(self, tabNum):
        tab_title = "New Tab : " + str(self.tab_index)
        self.tabWidget.addTab(Form(), tab_title)

    def MainButtonPressed(self):
        self.CreateNewTab(self.tab_index)
        findWidget = self.tabWidget.widget(self.tab_index).findChildren(QtGui.QPushButton, "tabButton")
        findWidget[0].clicked.connect(self.TabButtonPressed)
        findWidget = self.tabWidget.widget(self.tab_index).findChildren(QtGui.QLineEdit, "lineEdit")
        findWidget[0].editingFinished.connect(self.LineEditChanged)
        self.tab_index += 1

if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())

使用此功能不需要将每个标签页对象存储在列表中。您基本上使用QTabWidget索引您的页面,然后离开。

如果有人比这更优雅,请通知;)

1 个答案:

答案 0 :(得分:2)

正如我编辑过的问题所述,我确实找到了解决方法,即使用QTabWidget“索引”每个动态创建的标签页。

在QtDesigner中,我创建了一个主窗口,其中包含一个QTabWidget和一个按钮; enter image description here

这是对象树;

enter image description here

注意:我为“Click Me!”添加了一个信号/插槽。 QtDesigner中的按钮,以便在单击该按钮时,会调用 MainButtonPressed 函数。

为了填充标签页,我还在QtDesigner中创建了一个Form,其中包含一个按钮和一个QLineEdit小部件; enter image description here

对象树;

enter image description here

我将在这里重现代码。注意:我现在更新了这个答案,使用findChild而不是上面的findChildren:

import sys
from PyQt4.QtGui import *
from PyQt4.QtCore import *
from PyQt4 import QtGui
from example_Ui import Ui_MainWindow
from filler_Ui import Form

class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.setupUi(self)

    tab_index = 1 # 1 because we already made a default tab in QtDesigner

    def LineEditChanged(self):
        findWidget = self.tabWidget.widget(self.tabWidget.currentIndex()).findChild(QtGui.QLineEdit, "lineEdit")
        if findWidget.isModified() == True:
            print("LineEdit contents edited in tab page!")
        print("Name of page edited :", "'", self.tabWidget.tabText(self.tabWidget.currentIndex()),"'")

    def TabButtonPressed(self):
        print("YOU DID IT!")
        print("Current Tab Index = ", self.tabWidget.currentIndex())

    def CreateNewTab(self, tabNum):
        tab_title = "New Tab : " + str(self.tab_index)
        self.tabWidget.addTab(Form(), tab_title)

    def MainButtonPressed(self):
        self.CreateNewTab(self.tab_index)
        findWidget = self.tabWidget.widget(self.tab_index).findChild(QtGui.QPushButton, "tabButton")
        findWidget.clicked.connect(self.TabButtonPressed)
        findWidget = self.tabWidget.widget(self.tab_index).findChild(QtGui.QLineEdit, "lineEdit")
        findWidget.editingFinished.connect(self.LineEditChanged)
        self.tab_index += 1

if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())

运行时,按“Click Me!”主选项卡页面上的按钮创建一个新选项卡,并将“填充”页面的内容添加到其中。

变量tab_index会跟踪有多少个标签,并允许您引用每个标签的内容。

要在选项卡中查找窗口小部件,请使用Qt的findChild函数;

findWidget = self.tabWidget.widget(self.tab_index).findChild(QtGui.QPushButton, "tabButton")

查找特定小部件非常简单。您可以指定要查找的窗口小部件类型(QtGui.QPushButton),以及在QtDesigner中分配的名称(tabButton

在这种情况下,找到的小部件可以由变量findWidget引用。

然后您可以像往常一样将信号连接到功能插槽;

findWidget.clicked.connect(self.TabButtonPressed)

在这种情况下,我使用新式信号连接方法将clicked()信号连接到程序中名为TabButtonPressed的函数。

为您希望执行某些操作的标签页上的每个小部件进行冲洗和重复。

在那之后,它真的是一帆风顺;)

我希望这些信息有助于其他人的GUI工作。您可以使用与QToolBox小部件相同的技术。