Qmessagebox не работает

Я использую убунту линукс. Я использовал команду pyuic4 и создал файл .py, а затем добавил к нему окно сообщений. Вот оно:

from PyQt4 import QtCore, QtGui

try:
    _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
    _fromUtf8 = lambda s: s

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName(_fromUtf8("MainWindow"))
        MainWindow.resize(640, 480)
        self.centralwidget = QtGui.QWidget(MainWindow)
        self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
        self.pushButton = QtGui.QPushButton(self.centralwidget)
        self.pushButton.setGeometry(QtCore.QRect(190, 200, 98, 27))
        self.pushButton.setObjectName(_fromUtf8("pushButton"))
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtGui.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 640, 25))
        self.menubar.setObjectName(_fromUtf8("menubar"))
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtGui.QStatusBar(MainWindow)
        self.statusbar.setObjectName(_fromUtf8("statusbar"))
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QObject.connect(self.pushButton, QtCore.SIGNAL(_fromUtf8("clicked()")), self.about)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

def about(self):
    QtGui.QMessageBox.about(self, "Test", "This is a test.")

def retranslateUi(self, MainWindow):
    MainWindow.setWindowTitle(QtGui.QApplication.translate("MainWindow", "MainWindow", None, QtGui.QApplication.UnicodeUTF8))
    self.pushButton.setText(QtGui.QApplication.translate("MainWindow", "PushButton", None, QtGui.QApplication.UnicodeUTF8))
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_())

После долгих экспериментов я обнаружил, что это работает, если я изменю это: class Ui_MainWindow(object): на это: class Ui_MainWindow(QtGui.QMainWindow):

Я сделал большой сценарий, и я не знаю, вызовет ли он какие-либо проблемы или я делаю правильную вещь. Я просто сбит с толку. Пожалуйста, помогите и извините меня, если есть какие-либо проблемы в моем письме. Это мой первый пост.


person user2420437    schedule 19.07.2013    source источник


Ответы (1)


Я бы не стал использовать результат pyuic4 таким же образом. На самом деле я бы вообще не стал использовать pyuic4, но давайте посмотрим возможности:

Использование pyuic4

Допустим, у вас есть файл пользовательского интерфейса my_window.ui, в котором вы создаете виджет QMainWindow с именем MainWindow. С Designer вы также добавили связь между clicked действием кнопки и настраиваемым слотом about() (вы знаете, как создать пользовательский слот в Designer?). Теперь использование файла ui можно выполнить в 2 этапа:

  1. Вы создаете эквивалентный файл Python ui_my_window.py с помощью pyuic4:

    $ pyuic4 my_window.ui -o ui_my_window.py
    
  2. Затем вы создаете еще один файл Python (main.py), который импортирует файл ui_my_window.py. Не изменяйте файл, сгенерированный pyuic4! Он будет перезаписан, если вы повторно запустите команду pyuic4!

    $ cat main.py
    
    from PyQt4 import QtGui
    # import the class created py pyuic4
    from ui_my_window import Ui_MainWindow
    
    class MyMainWindow(QtGui.QMainWindow):
      def __init__(self, parent=None)
        QtGui.QMainWindow.__init__(self, parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
    
        # Beware that all widgets are now available through the self.ui attribute
        # Getting the push button is written:
        # self.ui.pushButton
    
      def about(self):
        # this is the custom slot created in Designer
        QtGui.QMessageBox.about(self, "Test", "This is a test.")
    
    if __name__ == "__main__":
      import sys
      app = QtGui.QApplication(sys.argv)
      myMainWindow = MyMainWindow()
      myMainWindow.show()
      sys.exit(app.exec_())
    

Итак, теперь у вас есть 3 файла:

      $ ls
      main.py ui_my_window.py my_window.ui

Просто запустите python main.py, чтобы запустить графический интерфейс.

Без использования pyuic4

PyQt4 предоставляет очень полезный модуль для работы с файлами пользовательского интерфейса: модуль uic. . На самом деле pyuic4 использует этот модуль для создания файла python из файла ui. Использование модуля позволяет избежать шага pyuic4 (Осторожно: если вы используете значки в файле ресурсов (.qrc), вам все равно нужно использовать инструмент pyrcc4 и импортировать полученный файл в свой код) .

В вашем примере код становится очень легким:

$ cat main.py

import os
from PyQt4 import QtGui
# import the uic module
from PyQt4 import uic

class MyMainWindow(QtGui.QMainWindow):
  def __init__(self, parent=None)
    QtGui.QMainWindow.__init__(self, parent)
    # Load the ui file
    uic.loadUi(os.path.join(os.path.dirname(os.path.abspath(__file__)),"my_window.ui"), self)

    # Now in this case, all widgets can directly be accessed because the last argument
    # of loadUi is self.
    # Getting the push button is written:
    # self.pushButton

  def about(self):
    # this is the custom slot created in Designer
    QtGui.QMessageBox.about(self, "Test", "This is a test.")

if __name__ == "__main__":
  import sys
  app = QtGui.QApplication(sys.argv)
  myMainWindow = MyMainWindow()
  myMainWindow.show()
  sys.exit(app.exec_())

В этом случае у вас есть только 2 файла:

      $ ls
      main.py my_window.ui

Снова просто запустите python main.py, чтобы запустить графический интерфейс.

person Frodon    schedule 22.07.2013
comment
Спасибо за ваше хорошее объяснение. Собственно, вместо pyuic4 my_window.ui -o ui_my_window.py я использую такую ​​команду: pyuic4 -x my_window.ui -o ui_my_window.py. - person user2420437; 23.07.2013
comment
Но проблема в следующем: класс MyMainWindow(QtGui.QMainWindow): когда мне нужно иметь этот класс MyMainWindow(object): чтобы я мог легко использовать Qmessagebox. Будет ли неправильно, если я вручную заменю объект на QtGui.QMainWindow? И я не знаю, как создать собственный слот в дизайнере. Пожалуйста, дайте мне знать. - person user2420437; 23.07.2013
comment
Опция -x генерирует исполняемый скрипт python, но в представленном мной случае он не будет работать, потому что метод about еще не существует. Чтобы добавить пользовательский слот из конструктора, щелкните правой кнопкой мыши в главном окне и выберите «Изменить сигналы/слоты» или что-то подобное (извините, моя версия не на английском языке). Появится окно, позволяющее добавить пользовательские сигналы и слоты в основной виджет. Если вы подключаете сигнал к пользовательскому слоту, не забудьте реализовать слот в унаследованном виджете, как я сделал в примере. - person Frodon; 23.07.2013
comment
Спасибо, Фродон. На самом деле, я сначала делаю исполняемый скрипт на Python. Затем я редактирую скрипт и добавляю свои необходимые функции и управляю сигналами и слотами. Это проще для меня. Мне не нужно писать слишком много вещей. - person user2420437; 23.07.2013
comment
Используя второй метод (без pyuic4), вам нечего писать ;) - person Frodon; 23.07.2013
comment
Я следовал вашим инструкциям и получил это сообщение об ошибке: AttributeError: объект QMainWindow не имеет атрибута about. Есть ли проблема в этой строке: QtCore.QObject.connect(self.pushButton, QtCore.SIGNAL(_fromUtf8(clicked()) ), MainWindow.о) - person user2420437; 23.07.2013
comment
Какие инструкции вы пробовали? Тот, кто использует pyuic4? - person Frodon; 23.07.2013
comment
Я смог вызвать окно, используя второй метод, но не получил кнопку. Можете ли вы найти здесь ошибку: if name == main: import sys app = QtGui.QApplication(sys.argv) MainWindow = QtGui.QMainWindow() ui = MyMainWindow( ) MainWindow.show() sys.exit(app.exec_()) - person user2420437; 23.07.2013
comment
Хорошо, я понимаю, это моя ошибка: в моем коде не хватало некоторых строк. Пожалуйста, перепроверьте мой ответ: я добавил часть if name == "main". - person Frodon; 23.07.2013
comment
Большой ! Спасибо Фродон. Оба метода работают сейчас. Сегодня я многому научился. - person user2420437; 23.07.2013