问题
I am trying to load a menubar onto my gui, but my class object has no attribute for self.menuBar(). Can someone help me, no tutorials seem to offer any way around.
class EmailBlast(QtWidgets.QWidget):
def __init__(self):
super().__init__()
bar = QtWidgets.menuBar()
file_menu = bar.addMenu('File')
file_edit = bar.addMenu('Edit')
Error message:
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'
What am I missing here.
Updated project:
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()
回答1:
Exception speaks truth: QWidget
class does not have a menuBar
attribute, QMainWindow has (as well as toolbars and status bar):
If you have QMainWindow
instance somewhere in your code and just want to fill menu items in EmailBlast
init, you can get menu bar of mentioned QMainWindow
by calling bar = QtWidgets.QMainWindow.menuBar()
. Menus consists of an QAction
s so you probably need to add them too.
If you do not have QMainWindow
then consider adding one. QMainWindow
must have "Central Widget". In your case it is probably EmailBlast
widget. Since EmailBlast
will be a part of MainWindow
you need to create and show MainWindow
instance instead of EmailBlast
.
If you have multiple elements (buttons, text edits etc.) in EmailBlast
widget then Qt layout system comes into play almost inevitable (quickly glance at pics in docs to grasp a concept).
It can be pretty hard to wrap a head around all this things at once, so once again.
QMainWindow - central part of your app. Has menu bar, toolbars, status bar and central area occupied by central widget.
Central widget - a widget providing main functionality of your app (or it can be a widget holding other widgets like QSplitter). In your case it is probably a EmailBlast
widget.
EmailBlast widget provides a piece of (reusable) functionality. To do so it itself consists of various helper widgets (text edits, buttons, check boxes and so on). To place this small widgets in a predictable manner the layout is created. Widgets are placed inside layout and layout is set to EmailBlast
widget.
Menu bar consists of zero or more QMenus, which in turn can have QActions. QAction signals (usually triggered
) are connecting to slots to provide desired behavior.
Here is a complete example:
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_())
This code produces nice little app like that:
来源:https://stackoverflow.com/questions/45680643/menubar-in-pyqt5