【问题标题】:Accessing GUI elements from outside GUI class in PyQt在 PyQt 中从外部 GUI 类访问 GUI 元素
【发布时间】:2017-05-06 19:25:00
【问题描述】:

注意:我已经阅读了this 的帖子,但很遗憾我没看懂。 我的目录设置有点像这样:

Main_Folder
|_ Base_Gui_File.py
|_ Child_directory (a directory inside Main_Folder)
  |_ __init__.py
  |_ some_other.py

我在Base_Gui_File.py 文件中获得了所有的GUI 代码,该文件是从designer(PyQt4) 生成的。有一个文本输入字段QLineEdit、一个按钮QPushButton和一个文本区域QTextBrowser

默认情况下QTextBrowser 是隐藏的。但是,我想做的是,当有人在QLineEdit 中键入内容并单击QPushButton 时,它会将字符串从QLineEdit 发送到some_other.py 文件中Child_Directory 中的方法.在使用该字符串执行某些操作后,some_other.py 文件中的方法将 showBase_Gui_File.py 中的 QTextBrowser 并在 QTextBrowser 中打印一些内容。

到目前为止,通过从QLineEdit 获取输入,我已经能够将字符串从Base_GUI_File.py 发送到some_other.py 文件。这是两个文件的代码:

some_other.py

import sys
sys.path.append("..")
from Base_Gui_File import Ui_MainWindow


class childone(object):
    """docstring for childone"""
    def __init__(self):
        super(childone, self).__init__()

    def somemethod(self, url):
        pass
        print 'Hey!'
        final_string = str(url) + "Just tying this!"
        print final_string

Base_Gui_file.py

# -*- coding: utf-8 -*-

from PyQt4 import QtCore, QtGui

try:
    _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
    def _fromUtf8(s):
        return s

try:
    _encoding = QtGui.QApplication.UnicodeUTF8
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig)

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName(_fromUtf8("MainWindow"))
        MainWindow.resize(800, 544)
        self.centralwidget = QtGui.QWidget(MainWindow)
        self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
        self.MyPushButton = QtGui.QPushButton(self.centralwidget)
        self.MyPushButton.setGeometry(QtCore.QRect(680, 40, 75, 23))
        self.MyPushButton.setObjectName(_fromUtf8("MyPushButton"))
        self.MyLabel = QtGui.QLabel(self.centralwidget)
        self.MyLabel.setGeometry(QtCore.QRect(30, 30, 46, 13))
        self.MyLabel.setObjectName(_fromUtf8("MyLabel"))
        self.MyTextArea = QtGui.QTextBrowser(self.centralwidget)
        self.MyTextArea.setGeometry(QtCore.QRect(20, 110, 721, 361))
        self.MyTextArea.setObjectName(_fromUtf8("MyTextArea"))
        self.MyTextField = QtGui.QLineEdit(self.centralwidget)
        self.MyTextField.setGeometry(QtCore.QRect(100, 30, 571, 41))
        self.MyTextField.setObjectName(_fromUtf8("MyTextField"))
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtGui.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 21))
        self.menubar.setObjectName(_fromUtf8("menubar"))
        self.menuFIle = QtGui.QMenu(self.menubar)
        self.menuFIle.setObjectName(_fromUtf8("menuFIle"))
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtGui.QStatusBar(MainWindow)
        self.statusbar.setObjectName(_fromUtf8("statusbar"))
        MainWindow.setStatusBar(self.statusbar)
        self.menubar.addAction(self.menuFIle.menuAction())

        self.MyPushButton.clicked.connect(self.download_click)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow", None))
        self.MyPushButton.setText(_translate("MainWindow", "PushButton", None))
        self.MyLabel.setText(_translate("MainWindow", "TextLabel", None))
        self.menuFIle.setTitle(_translate("MainWindow", "FIle", None))

    def download_click(self):
            self.MyTextArea.textCursor().insertHtml('Im HERE!') # This is working as it should
            url = str(self.MyTextField.text())

            from Child_directory.some_other import childone

            childone().somemethod(url)


if __name__ == "__main__":
    import sys
    app = QtGui.QApplication(sys.argv)
    MainWindow = QtGui.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

我该怎么做?两天前我开始了 GUI 和 OO 编程(Python),所以我对它非常陌生。所以,即使它只是一个正确方向的指南,那也很棒!

【问题讨论】:

    标签: python-2.7 pyqt pyqt4 qt-designer pyuic


    【解决方案1】:

    正如我在您链接到的答案中所说:编辑pyuic 生成的模块总是错误的。它是一个静态模块,可以导入到主程序中。

    此外,您的程序的当前结构向后看。主脚本应该在顶层,所有模块都应该在它下面的一个包中。这将确保您不需要做任何奇怪的sys.path 操作来导入您自己的模块。结构应该如下所示:

    program
        |_  main.py
        |_  package
            |_  __init__.py
            |_  app.py
            |_  gui.py
            |_  utils.py
    

    您的main.py 脚本应该非常简单,如下所示:

    if __name__ == '__main__':
    
        import sys
        from package import app
    
        sys.exit(app.run())
    

    这样做很重要,因为这个脚本的路径将成为sys.path中的第一个条目。这意味着您可以在程序中的任何其他模块中执行from package import xxx,并且导入将始终正常工作。

    app 模块应如下所示:

    import sys
    from PyQt4 import QtCore, QtGui
    from package.gui import Ui_MainWindow
    from package import utils
    
    class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
        def __init__(self, parent=None):
            super(MainWindow, self).__init__(parent)
            self.setupUi(self)
            self.MyPushButton.clicked.connect(self.download_click)
    
        def download_click(self):
            self.MyTextArea.textCursor().insertHtml('Hello World!')
            url = str(self.MyTextField.text())
            utils.some_func(url)
    
    def run():    
        app = QtGui.QApplication(sys.argv)
        window = MainWindow()
        window.show()
        return app.exec_()
    

    请注意,我已将您对 gui 模块所做的编辑移至 app 模块中。 MainWindow 类将拉入您在 Qt Designer 中添加的所有小部件,它们将成为类实例的属性。所以一旦你重新安排了你的程序,你应该使用pyuic重新生成gui模块。

    【讨论】:

    • 好的,太好了!这是有道理的。非常感谢所有这些提示,我发现自己经常制作奇怪的目录结构。您能否详细说明“因此,一旦您重新安排了程序,就应该使用 pyuic 重新生成 gui 模块”是什么意思?重新排列 GUI?
    • 不 - 我的意思是,一旦你完成了我建议的更改,你可以在你的设计器 ui 文件上重新运行 pyuic 以创建一个新的 gui 模块。这就是为什么您永远不应该编辑该文件的原因 - 每次在 qt 设计器中进行更改时,您都需要重新运行 pyuic,这将破坏您之前所做的任何编辑。
    • 嘿,抱歉耽搁了。我忙于考试。我按照你提到的做了,现在I ran into some weird problem。不过在这里感谢您的帮助!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-17
    相关资源
    最近更新 更多