目录
主窗口
QMainWindow
就是主窗口,QMainWindow
提供了更多的特性,如菜单栏、工具栏、状态栏和停靠窗口等,它是为复杂的主窗口应用设计的。QMainWindow
继承自 QWidget
,所以 QMainWindow
不仅可以使用 QWidget
的所有功能,还有额外的功能。
也就是说,在需要更复杂、更全面的情况时,用 QMainWindow
会更好,至于具体的使用可以看后面的内容。
状态栏
举例————创建一个状态栏并显示消息“Ready”:
statusBar = self.statusBar()
statusBar.showMessage('Ready')
讲解:
- 这个方法可以创建一个状态栏:
statusBar = self.statusBar()
- 但也仅限于创建了状态栏,是没有显示任何信息的,所以得通过下面这个方法给状态栏加上一条消息:
statusBar.showMessage('Ready')
动作组合
这个比较特殊,单就它自己用的话,鸟用没有,得组合上其他的部分一起用才行。
QAction
是菜单栏、工具栏或者快捷键的动作的组合,举例就是如下:
exitAct = QAction(QIcon('exit.png'), '&Exit', self)
exitAct.setShortcut('Ctrl+Q')
exitAct.setStatusTip('Exit application')
exitAct.triggered.connect(qApp.quit)
然后现在来详细讲解:
- 第一行代码,有三个作用分别对应三个参数:
exitAct = QAction(QIcon('exit.png'), '&Exit', self)
QIcon('exit.png')
为动作添加一个图标。'&Exit'
,为动作命名(在&
之后的Exit
才是名字)。self
这个动作要绑定在哪个组件上。
- 第二行代码,为动作添加一个快捷键:
exitAct.setShortcut('Ctrl+Q')
这里的快捷键是会自动根据字符串来进行更改的,也就是既可以是'Ctrl+Q'
,也可以是'Ctrl+K
, 同样可以是'shift+Q'
,具体更多的作用就自己上网搜或者自己尝试吧。 - 第三行代码,当鼠标放在动作上时,会出现状态消息:
exitAct.setStatusTip('Exit application')
也就是要跟上面说到的状态栏的知识配合使用的,切记,要在代码中先创建状态栏,才能正常显示状态消息,也就是要有这一段代码
self.statusBar()
- 第四行代码,给动作绑定一个事件,这里的事件是结束应用程序:
exitAct.triggered.connect(qApp.quit)
这里更多的就不说了,反正拿来用就行了,更多的事情可以自己试试。
菜单栏
举例————创建一个菜单栏并给菜单栏添加一个结束应用程序的动作:
exitAct = QAction(QIcon('exit.png'), '&Exit', self)
exitAct.setShortcut('Ctrl+Q')
exitAct.setStatusTip('Exit application')
exitAct.triggered.connect(self.close)
self.statusBar()
menubar = self.menuBar()
menubar.addAction(exitAct)
详细讲解:
- 先用上面所说的 动作组件 的内容创建一个动作并设定具体内容:
exitAct = QAction(QIcon('exit.png'), '&Exit', self)
exitAct.setShortcut('Ctrl+Q')
exitAct.setStatusTip('Exit application')
exitAct.triggered.connect(self.close)
self.statusBar()
- 创建一个菜单栏:
menubar = self.menuBar()
- 为子菜单添加一个动作(正是第1步代码里创建的动作):
menubar.addAction(exitAct)
子菜单
举例————给“菜单”的内容加上一个子菜单“File”并将结束应用程序的动作移进去:
exitAct = QAction(QIcon('exit.png'), '&Exit', self)
exitAct.setShortcut('Ctrl+Q')
exitAct.setStatusTip('Exit application')
exitAct.triggered.connect(self.close)
self.statusBar()
menubar = self.menuBar()
fileMenu = QMenu("File", self)
fileMenu.addAction(exitAct)
menubar.addMenu(fileMenu)
详细讲解:
因为这一部分内容跟“菜单”的内容相差不大,所以我就只讲解不同的部分了
- 创建一个子菜单名叫 File 并且是在
self
组件上:
fileMenu = QMenu("File", self)
- 为这个子菜单添加动作:
fileMenu.addAction(exitAct)
- 把子菜单添加进菜单里:
menubar.addMenu(fileMenu)
顺带一提,这种操作是可以嵌套的,也就是可以给子菜单添加子子菜单。
勾选菜单
勾选菜单的关键代码是以下这几行:
viewStatAct = QAction('View statusbar', self, checkable=True)
viewStatAct.setStatusTip('View statusbar')
viewStatAct.setChecked(True)
viewStatAct.triggered.connect(self.toggleMenu)
viewMenu.addAction(viewStatAct)
接下来逐一进行讲解:
- 创建一个可勾选动作:
viewStatAct = QAction('View statusbar', self, checkable=True)
关键在于这个参数checkable=True
,也就是使得该动作是可勾选的。 - 这里是 状态栏 的知识,也就是当鼠标放在这个动作上的时候,会有一条状态信息。
viewStatAct.setStatusTip('View statusbar')
- 设置动作的默认状态为已选中:
viewStatAct.setChecked(True)
- 给动作绑定一个事件:
viewStatAct.triggered.connect(self.toggleMenu)
- 给菜单添加该动作:
viewMenu.addAction(viewStatAct)
关键就在于第一步和第三步,其他的其实就是菜单的常规流程。
然后现在还有一个需要注意的点————由该动作调用的方法会自动传递一个布尔值的参数,以下是上面示例中动作所绑定的方法:
def toggleMenu(self, state):
if state:
self.statusbar.show()
else:
self.statusbar.hide()
这时候会发现,这个方法还需要接收一个 state
的参数,才能正常运行。
所以需要注意以下这些内容:
当 QAction
的 triggered
信号被触发时(即用户点击了这个 QAction
对象),它会传递一个参数,这个参数的值是 QAction
的选中状态(如果 QAction
是可选的)。这个值是一个布尔值:如果 QAction
被选中,值是 True ;如果 QAction
没有被选中,值是 False。
同时这个方法还决定了你鼠标放在动作上时,消息会不会显示出来。
右键菜单
右键菜单,也就是当我们在指定位置点击鼠标右键时会出现的菜单。
举例————创建一个右键上下文菜单,包含 "New", "Open", 和 "Quit" 三个选项,其中 "Quit" 能结束应用程序:
def contextMenuEvent(self, event):
cmenu = QMenu(self)
newAct = cmenu.addAction("New")
opnAct = cmenu.addAction("Open")
quitAct = cmenu.addAction("Quit")
action = cmenu.exec_(self.mapToGlobal(event.pos()))
if action == quitAct:
qApp.quit()
详细讲解:
- 定义一个上下文菜单事件处理函数:
def contextMenuEvent(self, event)
注意,方法名必须是contextMenuEvent
,具体看下面的内容。 - 创建一个上下文菜单 cmenu,并关联到当前的组件 (self):
cmenu = QMenu(self)
- 创建三个动作
newAct
,opnAct
,quitAct
,并添加到上下文菜单cmenu
中:
newAct = cmenu.addAction("New")
opnAct = cmenu.addAction("Open")
quitAct = cmenu.addAction("Quit")
- 显示上下文菜单,并获取用户选择的动作。如果用户没有选择任何动作,
exec_()
方法会返回 None:
action = cmenu.exec_(self.mapToGlobal(event.pos()))
在这段代码中使用exec_()
方法显示菜单。从鼠标右键事件对象中获得当前坐标。mapToGlobal()
方法把当前组件的相对坐标转换为窗口(window)的绝对坐标。
也就是说,这一段代码实现了在当前鼠标处显示上下文菜单。 - 最后,我们检查用户是否选择了 "Quit" 动作。如果是,就关闭应用程序:
if action == quitAct: qApp.quit()
在这段代码中,右键上下文菜单是通过重写 contextMenuEvent()
方法实现的,这是一个 PyQt5 的特性。当用户在窗口部件上右键点击时,contextMenuEvent()
方法会被自动调用。在这个方法中,你可以定义当用户右键点击时要做什么,例如显示一个上下文菜单。
工具栏
工具栏,一种常见的用户界面元素,它包含一些常用的操作或命令的图标。在PyQt5中,我们可以通过addToolBar()
方法添加工具栏,并通过addAction()
方法添加工具栏项。
举例————创建一个工具栏并给工具栏添加一个结束应用程序的动作:
exitAct = QAction(QIcon('exit24.png'), 'Exit', self)
exitAct.setShortcut('Ctrl+Q')
exitAct.triggered.connect(qApp.quit)
self.toolbar = self.addToolBar('Exit')
self.toolbar.addAction(exitAct)
详细讲解:
- 创建一个动作及相关内容:
exitAct = QAction(QIcon('exit24.png'), 'Exit', self)
exitAct.setShortcut('Ctrl+Q')
exitAct.triggered.connect(qApp.quit)
- 通过addToolBar方法创建一个工具栏,名字为Exit:
self.toolbar = self.addToolBar('Exit')
- 将动作添加到工具栏中:
self.toolbar.addAction(exitAct)
在这段代码中,工具栏的名字 Exit 只是一个内部标识符,用户是看不到这个名字的。当我们为工具栏添加动作时,动作的图标和名字会显示在工具栏上,用户可以通过点击工具栏上的图标来触发动作。
值得注意的是,工具栏和菜单栏类似,也支持快捷键和触发事件。
关闭当前窗口和结束应用程序
self.close
会尝试关闭当前窗口。如果这个窗口是应用程序的主窗口,那么应用程序将会结束。但是如果这个窗口是一个子窗口,那么应用程序会继续运行。qApp.quit
会直接结束应用程序,关闭所有的窗口,无论当前窗口是主窗口还是子窗口。