从其他模块引用的其他函数访问PyQt4 UI元素

时间:2013-05-29 19:08:44

标签: python pyqt4 qt-designer

我正在使用Qt设计器使用PyQt4。这是我第一次使用它,所以我只是想了解一些事情,但这让我很难过。

我遇到的问题是,一旦定义并创建了UI窗口,我就会尝试调用一个函数来更新UI元素,并产生“未定义”的错误。

但是,如果我将相同的代码放在最初定义元素的代码块中,它就可以正常工作。

我在下面写了一个例子来说明我的意思。

问题是我需要调用来更新来自不同模块的lcd编号,该模块包含单击按钮时调用的函数。

为了表明这一点,我在qtdesigner中创建了一个带有lcdnumber(lcd1)和一个按钮(button1)的表单,编译了“testui.py”文件中的代码,该文件创建了“MainWindow”类。

在a.py中,我说:

import testui as interface
import sys
import b
from PyQt4 import QtCore,  QtGui

ui= interface.Ui_MainWindow()

def updateui():
   for i in range(0, 100):
       ui.lcd1.setProperty("value", i)

if __name__ == "__main__":
   app = QtGui.QApplication(sys.argv)
   test = QtGui.QMainWindow()
   ui.setupUi(test)
   ui.lcd1.setProperty("value", 1)
   ui.button1.clicked.connect(b.updatelcd)
   test.show()
   app.exec_()

这将打开窗口,并设置初始状态并将按钮连接到b.py。

中的函数

在b.py中,我放了:

from a import updateui

def updatelcd():
   updateui()

当我点击按钮时,它会调用a.py中的函数,这会导致错误:

“模块没有属性lcd1”

这让我困惑了一段时间,因为ui.lcd1.setProperty在循环中工作!

对于我正在做的事情,这一定是根本上的错误,但是我无法解决这个问题。

赞赏任何想法

由于

1 个答案:

答案 0 :(得分:1)

你正在做一些循环导入,这本身并不是一个好主意。

这里发生的是:
当您导入updateui时,ui变量未导入。
ui变量可能是gloabal,但仅限于您的模块 因此,当您调用updatelcd中的b函数调用从updateui导入的a时,NameErrorlcd1,因为ui是没有初始化。

实际上我并不确定为什么它首先不抱怨ui。可能是python导入的知识是在。

中定义了一个全局变量ui

您应该考虑如何在没有循环导入的情况下实现目标,而不是仅导入函数'updateui fromin b and including b in a`。

你不仅要考虑模块,还要考虑课程。使其面向对象。 那么你能做什么:
1.在b模块中创建一个类,它可以按照模块现在的方式执行所有操作 2.创建一个以interface.Ui_MainWindow()为参数的构造函数并存储它 3.然后,您将能够执行您的updatelcd(无需使用a中定义的任何方法) 4.在a-module中创建b-class的实例。在这个实例中,您可以调用更新lcd的函数。

这是你的b级代码看起来像什么

class B:
  __init__(self, mainWindow):
    self.mainWindow = mainWindow

  def updatelcd(self):
    for i in range(0, 100):
      self.mainWindow.lcd1.setProperty("value", i)

所以模块a看起来像这样:

import testui as interface
import sys
import b
from PyQt4 import QtCore,  QtGui

ui= interface.Ui_MainWindow()
thing = b.B(ui) 

if __name__ == "__main__":
 app = QtGui.QApplication(sys.argv)
 test = QtGui.QMainWindow()
 ui.setupUi(test)
 ui.lcd1.setProperty("value", 1)
 ui.button1.clicked.connect(thing.updatelcd())
 test.show()
 app.exec_()