2017-08-14 69 views
-2

我想加載一個菜單到我的GUI,但我的類對象沒有self.menuBar()的屬性。有人可以幫助我,沒有任何教程似乎提供任何方式。在PyQt5 menuBar()

class EmailBlast(QtWidgets.QWidget): 
    def __init__(self): 
     super().__init__() 
     bar = QtWidgets.menuBar() 
     file_menu = bar.addMenu('File') 
     file_edit = bar.addMenu('Edit')   

錯誤消息:

File "BasicEmail.py", line 84, in email_config 
self.ui = EmailBlast() 
File "BasicEmail.py", line 96, in __init__ 
self.menuBar() 
AttributeError: 'EmailBlast' object has no attribute 'menuBar' 

缺少什麼我在這裏。

更新項目:

class MainWindow(QtWidgets.QMainWindow): 
def __init__(self): 
    super().__init__() 
    self.email_blast_widget = EmailBlast() 
    self.setCentralWidget(self.email_blast_widget) 
    bar = self.menuBar() 
    file_file = bar.addMenu('File')   
    file_edit = bar.addMenu('Edit') 

class EmailBlast(QtWidgets.QWidget): 
def __init__(self): 
    super().__init__() 
    self.text_box = QtWidgets.QTextEdit(self) 
    self.save_button = QtWidgets.QPushButton('Save') 
    self.clear_button = QtWidgets.QPushButton('Clear')   
    self.open_button = QtWidgets.QPushButton('Open')   
    self.init_ui() 

回答

3

例外講道理:QWidget類沒有一個menuBar屬性,QMainWindow有(以及工具欄和狀態欄):

QMainWindow layout

如果您在你的代碼的某個地方有QMainWindow實例,並且只想填入EmailBlast init中的菜單項,就可以獲得提到的的菜單欄致電bar = QtWidgets.QMainWindow.menuBar()。菜單由QAction組成,因此您可能需要添加它們。

如果您沒有QMainWindow,請考慮添加一個。 QMainWindow必須有「中央小工具」。在你的情況下,它可能是EmailBlast部件。由於EmailBlast將成爲MainWindow的一部分,因此您需要創建並顯示MainWindow實例,而不是EmailBlast

如果在EmailBlast小部件中有多個元素(按鈕,文本編輯等),那麼Qt layout system幾乎不可避免地發揮作用(快速瀏覽文檔中的圖片以掌握概念)。

要一次把所有這些東西都包起來很難,所以再一次。

QMainWindow - 您的應用程序的核心部分。有菜單欄,工具欄,狀態欄和中央區域佔用的中央部件

中央部件 - 一個小部件,提供您的應用程序的主要功能(或者它可以是一個小部件,其他部件如QSplitter)。在你的情況下,它可能是一個EmailBlast部件。

EmailBlast小部件提供了一塊(可重用)功能。要做到這一點,它本身由各種助手小部件(文本編輯,按鈕,複選框等)組成。爲了以可預見的方式放置這些小小部件,創建了佈局。小部件放置在佈局中,佈局設置爲EmailBlast小部件。

菜單欄由零個或多個QMenu s組成,其中可以有QAction s。 QAction信號(通常爲triggered)連接到插槽以提供所需的行爲。

下面是一個完整的例子:

import sys 
from PyQt5 import QtWidgets 


class MainWindow(QtWidgets.QMainWindow): 
    def __init__(self, parent=None): 
     super().__init__(parent) 
     # creating EmailBlast widget and setting it as central 
     self.email_blast_widget = EmailBlast(parent=self) 
     self.setCentralWidget(self.email_blast_widget) 
     # filling up a menu bar 
     bar = self.menuBar() 
     # File menu 
     file_menu = bar.addMenu('File') 
     # adding actions to file menu 
     open_action = QtWidgets.QAction('Open', self) 
     close_action = QtWidgets.QAction('Close', self) 
     file_menu.addAction(open_action) 
     file_menu.addAction(close_action) 
     # Edit menu 
     edit_menu = bar.addMenu('Edit') 
     # adding actions to edit menu 
     undo_action = QtWidgets.QAction('Undo', self) 
     redo_action = QtWidgets.QAction('Redo', self) 
     edit_menu.addAction(undo_action) 
     edit_menu.addAction(redo_action) 

     # use `connect` method to bind signals to desired behavior 
     close_action.triggered.connect(self.close) 


class EmailBlast(QtWidgets.QWidget): 
    def __init__(self, parent=None): 
     super().__init__(parent) 
     # create and set layout to place widgets 
     grid_layout = QtWidgets.QGridLayout(self) 

     self.text_box = QtWidgets.QTextEdit(self) 
     self.save_button = QtWidgets.QPushButton('Save') 
     self.clear_button = QtWidgets.QPushButton('Clear') 
     self.open_button = QtWidgets.QPushButton('Open') 
     # add widgets to layout. Params are: 
     # (widget, fromRow, fromColumn, rowSpan=1, columnSpan=1) 
     grid_layout.addWidget(self.text_box, 0, 0, 1, 3) 
     grid_layout.addWidget(self.save_button, 1, 0) 
     grid_layout.addWidget(self.clear_button, 1, 1) 
     grid_layout.addWidget(self.open_button, 1, 2) 


if __name__ == '__main__': 
    app = QtWidgets.QApplication(sys.argv) 
    # creating main window 
    mw = MainWindow() 
    mw.show() 
    sys.exit(app.exec_()) 

此代碼生成可愛的小應用程序那樣:

app window

+0

我建議你把小部件的佈局裏面,並把裏面的這種佈局centralWidget。 – eyllanesc

+0

這個想法是幫助問題的作者,如果你把代碼不起作用會混淆作者。另一種選擇是刪除該部分並顯示必要的代碼。 – eyllanesc

+0

@eyllanesc,公平點。我試圖更新答案以儘量減少混淆。 – 9dogs