【问题标题】:Accessing Action Buttons from Another File PyQt4从另一个文件 PyQt4 访问操作按钮
【发布时间】:2018-03-08 10:30:21
【问题描述】:

我有一个由 Pyqt4 的 pyuic 生成的 .py 文件。在这个文件中,我有一个工具栏和一个连接到actionRotate 操作的旋转图标。这是代码的一小部分;

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_Program(object):
    def setupUi(self, UI_Class):
        UI_Class.setObjectName(_fromUtf8("UI_Class"))
               ... 
        self.toolBar = QtGui.QToolBar(UI_Class)
        self.toolBar.setObjectName(_fromUtf8("toolBar"))
        UI_Class.addToolBar(QtCore.Qt.TopToolBarArea, self.toolBar)
        self.toolBar.addAction(self.actionRotate)
        self.actionRotate = QtGui.QAction(UI_Class)
        self.actionRotate.setCheckable(True)
        self.actionRotate.setIcon(icon10)
        self.actionRotate.setObjectName(_fromUtf8("actionRotate"))

因此,如果我尝试访问 actionRotate 按钮,无论是否从另一个类中检查它,它的工作原理就像底部示例中一样;

import PyQt4
import sys
from PyQt4.QtGui import *
from PyQt4 import QtGui, QtCore
from PyQt4 import QtGui
from DropDownActions import *
import pickle
import OpenGLcode
from OpenGL.GL import *
import PYQT_PROGRAM
import numpy as np
import sqlite3 as sq

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

try:
    from OpenGL import GL
except ImportError:
    app = QtGui.QApplication(sys.argv)
    QtGui.QMessageBox.critical(None, "OpenGL hellogl",
            "PyOpenGL must be installed to run this example.")
    sys.exit(1)

class UI_main_subclass(QMainWindow):

    def __init__(self, ui_layout):

        QMainWindow.__init__(self)
        self.ui = ui_layout
        ui_layout.setupUi(self)
        ....
        var1 = ui_layout.actionRotate.isChecked()

但是当我尝试从我的 OpenGL 代码中执行操作时,我无法实现这一点。下面的代码显示了相关部分;

from OpenGL.GL import *
from PyQt4.QtOpenGL import *
from PyQt4 import QtCore

class glWidget(QGLWidget, QMainWindow):
    resized = QtCore.pyqtSignal()

    xRotationChanged = QtCore.pyqtSignal(int)
    yRotationChanged = QtCore.pyqtSignal(int)
    zRotationChanged = QtCore.pyqtSignal(int)

    def __init__(self, ui_layout, parent = None):
        super(glWidget,self).__init__(parent)

    def mousePressEvent(self, event):
        if self.ui.actionRotate.isChecked(self): # this code gives error below
            print("test 1")
            x, y = event.x(), event.y()
            w, h = self.width(), self.height()
            # required to call this to force PyQt to read from the correct, updated buffer
            glReadBuffer(GL_FRONT)
            data = self.grabFrameBuffer()  # builtin function that calls glReadPixels internally
            rgba = QColor(data.pixel(x, y)).getRgb()  # gets the appropriate pixel data as an RGBA tuple
            message = "You selected pixel ({0}, {1}) with an RGBA value of {2}.".format(x, y, rgba)

            self.lastPos = event.pos()

        else:
            pass

错误是;

AttributeError: 'glWidget' object has no attribute 'ui'

我不确定为什么这不允许我从 pyuic 访问主 .py 文件中生成的操作按钮?

感谢任何帮助...

【问题讨论】:

  • 包含glWidget 类的模块甚至不导入Ui_ProgramUI_main_subclass,更不用说尝试以任何方式使用它们了。所以我不明白你为什么认为它应该起作用。
  • 我实际上是用import UI_Program 导入的,但我无法导入UI_main_subclass,因为glWidget 类文件在UI_main_subclass 中很重要。
  • 但是glWidget没有继承UI_Program,也没有创建它的实例。那么为什么你认为它应该有一个ui 属性呢?
  • 如何强制glWidget 也从UI_Program 继承?
  • 您可以从这些 github 页面归档我的文件; linklinklink

标签: python class pyqt4 pyopengl action-button


【解决方案1】:

您似乎已经准备好了大部分内容:您只需要正确使用它们即可。

在您的主窗口类中,将ui_layout 传递给glWidget

class SABRE2_main_subclass(QMainWindow):    
    def __init__(self, ui_layout):
        QMainWindow.__init__(self)
        self.ui = ui_layout
        ...
        self.OpenGLwidget = OpenGLcode.glWidget(ui_layout)

然后在glWidget中保留对它的引用:

class glWidget(QGLWidget, QMainWindow):    
    def __init__(self, ui_layout, parent = None):
        super(glWidget,self).__init__(parent)
        self.ui = ui_layout

现在glWidget可以访问ui_layout的属性了:

    def mousePressEvent(self, event):
        if self.ui.actionRotate.isChecked():
            print("test 1")

【讨论】:

  • 谢谢,这解决了操作按钮的问题,但它会在glWidget 的第 86 行抛出带有 DropDownActions.statusMessage(self.ui, message) 的箭头。我该如何解决?
  • 您将不得不在glWidget 的任何地方使用self.ui 而不是self.ui_layout(请参阅我的答案中的修改代码)。然后你应该能够做到DropDownActions.statusMessage(self, message)(因为self 现在将有一个ui 属性)。 (PS:如果您觉得这个答案有用,请点赞/接受)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-12
  • 1970-01-01
  • 2014-10-13
  • 1970-01-01
  • 2017-08-15
  • 2021-04-18
相关资源
最近更新 更多