PyQt:.UI中的按钮在运行时不显示

时间:2012-07-13 20:15:20

标签: python pyqt4

解决
我改变了:

  

self.ui = base_class()

进入:

  

self.ui = form_class()
          self.ui.setupUi(self)

现在它有效!


我正在尝试使用一些代码,以便我可以动态使用.ui文件。这样,当我运行python代码时,会立即使用Qt Designer进行更新。

在摆弄和使用片段后,我最终得到以下代码。但不知何故,.ui中的按钮没有显示。有人有想法吗?

import sys,os

from PyQt4 import QtCore, QtGui, uic

form_class, base_class = uic.loadUiType('try_ui.ui')

class MainWindow(QtGui.QMainWindow):
    def __init__(self, parent = None):
        QtGui.QWidget.__init__(self, parent)
        self.ui = base_class()

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

和try_ui.ui一个简单的按钮:

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>323</width>
    <height>111</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <widget class="QWidget" name="centralwidget">
   <widget class="QPushButton" name="pushButton">
    <property name="geometry">
     <rect>
      <x>120</x>
      <y>30</y>
      <width>75</width>
      <height>23</height>
     </rect>
    </property>
    <property name="text">
     <string>PushButton</string>
    </property>
   </widget>
  </widget>
  <widget class="QMenuBar" name="menubar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>323</width>
     <height>21</height>
    </rect>
   </property>
  </widget>
  <widget class="QStatusBar" name="statusbar"/>
 </widget>
 <resources/>
 <connections/>
</ui>

2 个答案:

答案 0 :(得分:0)

这是一个工作示例,显示单击按钮时的消息框。您当然需要上面的UI示例。

import sys,os

from PyQt4 import QtCore, QtGui, uic

form_class, base_class = uic.loadUiType('try_ui.ui')

class MainWindow(QtGui.QMainWindow):
    MESSAGE = "Hello!"
    def __init__(self, parent = None):
        QtGui.QMainWindow.__init__(self, parent)
        self.ui = form_class()
        self.ui.setupUi(self)
        self.ui.pushButton.clicked.connect(self.informationMessage)
    def informationMessage(self):
        reply = QtGui.QMessageBox.information(self,
                "QMessageBox.information()", MainWindow.MESSAGE)

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

答案 1 :(得分:0)

对于那些喜欢PySide的人。

import sys,os

from PySide import QtCore, QtGui, QtUiTools

class MainWindow(QtGui.QMainWindow):
    MESSAGE = "Hello!"
    def __init__(self, parent=None):
        QtGui.QMainWindow.__init__(self, parent)
        self.ui = loadUi(os.path.join(os.getcwd(), "try_ui.ui"), self)
        self.ui.pushButton.clicked.connect(self.informationMessage)
    def informationMessage(self):
        reply = QtGui.QMessageBox.information(self,
                "QMessageBox.information()", MainWindow.MESSAGE)

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

您需要包含类UiLoader和loadUi。它们来自:https://github.com/lunaryorn/snippets/blob/master/qt4/designer/pyside_dynamic.py

class UiLoader(QtUiTools.QUiLoader):
    """
    Subclass :class:`~PySide.QtUiTools.QUiLoader` to create the user interface
    in a base instance.

    Unlike :class:`~PySide.QtUiTools.QUiLoader` itself this class does not
    create a new instance of the top-level widget, but creates the user
    interface in an existing instance of the top-level class.

    This mimics the behaviour of :func:`PyQt4.uic.loadUi`.
    """

    def __init__(self, baseinstance):
        """
        Create a loader for the given ``baseinstance``.

        The user interface is created in ``baseinstance``, which must be an
        instance of the top-level class in the user interface to load, or a
        subclass thereof.

        ``parent`` is the parent object of this loader.
        """
        QtUiTools.QUiLoader.__init__(self, baseinstance)
        self.baseinstance = baseinstance

    def createWidget(self, class_name, parent=None, name=''):
        if parent is None and self.baseinstance:
            # supposed to create the top-level widget, return the base instance
            # instead
            return self.baseinstance
        else:
            # create a new widget for child widgets
            widget = QtUiTools.QUiLoader.createWidget(self, class_name, parent, name)
            if self.baseinstance:
                # set an attribute for the new child widget on the base
                # instance, just like PyQt4.uic.loadUi does.
                setattr(self.baseinstance, name, widget)
            return widget


def loadUi(uifile, baseinstance=None):
    """
    Dynamically load a user interface from the given ``uifile``.

    ``uifile`` is a string containing a file name of the UI file to load.

    If ``baseinstance`` is ``None``, the a new instance of the top-level widget
    will be created.  Otherwise, the user interface is created within the given
    ``baseinstance``.  In this case ``baseinstance`` must be an instance of the
    top-level widget class in the UI file to load, or a subclass thereof.  In
    other words, if you've created a ``QMainWindow`` interface in the designer,
    ``baseinstance`` must be a ``QMainWindow`` or a subclass thereof, too.  You
    cannot load a ``QMainWindow`` UI file with a plain
    :class:`~PySide.QtGui.QWidget` as ``baseinstance``.

    :method:`~PySide.QtCore.QMetaObject.connectSlotsByName()` is called on the
    created user interface, so you can implemented your slots according to its
    conventions in your widget class.

    Return ``baseinstance``, if ``baseinstance`` is not ``None``.  Otherwise
    return the newly created instance of the user interface.
    """
    loader = UiLoader(baseinstance)
    widget = loader.load(uifile)
    QtCore.QMetaObject.connectSlotsByName(widget)
    return widget