2017-08-14 43 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