PyQt5教程 (结合designer使用)--- (三)Menus and toolbars

QStatusBar(*)

如果要动态更改Statusbar,则只能用代码实现,简单的静态设置还是可以用designer(不过statusbar本身的功能需求就是动态的吧。。。)
在这里插入图片描述

import sys
from PyQt5.QtWidgets import QMainWindow, QApplication
class Example(QMainWindow):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        self.statusBar().showMessage('Ready')

        self.setGeometry(300, 300, 250, 150)
        self.setWindowTitle('Statusbar')
        self.show()


def main():
    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())

if __name__ == '__main__':
main()

在这里插入图片描述

使用QMainWindow提供的方法statusBar来实现
第一次调用statusBar()时创建status bar对象,之后的调用都是返回这个已创建的status bar对象
在这里插入图片描述

QMenuBar(*)

在这里插入图片描述

Mac OS对菜单栏的处理不一样

import sys
from PyQt5.QtWidgets import QMainWindow, QAction, qApp, QApplication
from PyQt5.QtGui import QIcon


class Example(QMainWindow):
    def __init__(self):
        super().__init__()

        self.initUI()

    def initUI(self):
        exitAct = QAction(QIcon('exit.png'), '&Exit', self)  # we create an action with a specific icon and an 'Exit' label.
        exitAct.setShortcut('Ctrl+Q')                  #a shortcut is defined for this action.
        exitAct.setStatusTip('Exit application')         #creates a status tip which is shown in the statusbar when we hover a mouse pointer over the menu item.
        exitAct.triggered.connect(qApp.quit)          #When we select this particular action, a triggered signal is emitted. The signal is connected to the quit() method of the QApplication widget. This terminates the application.

        self.statusBar()

        menubar = self.menuBar()              #The menuBar() method creates a menubar. 类似于statusBar,同样使用QMainWindow对象的menuBar方法来创建菜单栏
        fileMenu = menubar.addMenu('&File')     #create a file menu with addMenu()
        fileMenu.addAction(exitAct)            #add the action with addAction().

        self.setGeometry(300, 300, 300, 200)
        self.setWindowTitle('Simple menu')
        self.show()

def main():
    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())

if __name__ == '__main__':
main()

在这里插入图片描述

exitAct.triggered.connect(qApp.quit)
这行代码完全可以改成exitAct.triggered.connect(QApplication.instance().quit)
效果一样,都是退出程序,上面代码导入了一个aApp模块,利用它里面的quit方法

QAction is an abstraction for actions performed with a menubar, toolbar, or with a custom keyboard shortcut.
QAction专用于menubar、toolbar和快捷键的功能实现,用QAction连接槽函数

上面完全可以使用designer来实现,QAction那些方法都可以直接生成
下面先看信号与槽的知识

信号与槽1

在这里插入图片描述
在这里插入图片描述

左边为signal,右边为slot!
Signal函数的参数表明其会发送这些参数,slot函数中的参数表明要接收这些参数
(Signal函数发送的参数个数必须大于等于slot接收的参数个数)

因为上面是从pushButton拖动到空白处,因此,signal为pushButton,slot为MainWindow
若是拖动到另外的控件上,则slot为另外的控件!
在这里插入图片描述

如左边为pressed信号,右边选click槽
在这里插入图片描述

生成的代码有如下
在这里插入图片描述

写一个最简单的逻辑文件,main2.py

import sys
from PyQt5.QtWidgets import QApplication, QMainWindow
import test2
if __name__ == "__main__":
    app=QApplication(sys.argv)
    Mainwindow=QMainWindow()
    ui=test2.Ui_MainWindow()
    ui.setupUi(Mainwindow)
    Mainwindow.show()
    sys.exit(app.exec_())

在这里插入图片描述

点击button就相当于点击CheckBox了!

还可以自定义槽
引线时点击Edit可以进入定义槽的界面
在这里插入图片描述

或者直接在widget上右键,点击change signals/slots进入
在这里插入图片描述

self.pushButton.clicked.connect(MainWindow.slot1)

生成的代码如上,但这样需要在代码中继承QMainWindow类,然后定义slot1方法
(虽然可以直接修改生成的ui.py代码,如上面直接修改成

self.pushButton.clicked.connect(slot1)

但因为更新一次ui,就得改一次,还是不太好,要分隔开ui设计与逻辑好一点

下面用designer来实现上一节的代码
注意,designer中主要是使用引一条线的方式来设置信号与槽,但是目录下面的QAction对象在引线时藏在menubar里面了,因此引线方式无法给QAction配置
在这里插入图片描述

但是还可以使用右下角的signal/slot editor来编辑!
在这里插入图片描述

生成如下代码
在这里插入图片描述

编辑逻辑代码部分

import sys
from PyQt5.QtWidgets import QMainWindow, , QApplication
import test

class Example(QMainWindow):
    def __init__(self):
        super().__init__()
    def slot1(self):
        QApplication.instance().quit()
        
def main():
    app = QApplication(sys.argv)
    ex = Example()
    ui=test.Ui_MainWindow()
    ui.setupUi(ex)
    ex.show()
    sys.exit(app.exec_())

if __name__ == '__main__':
        main()

在这里插入图片描述

可以实现同样的功能,点击exit退出程序

Submenu(**)

在这里插入图片描述

完全可以使用designer配合完成,这里演示使用designer

import sys
from PyQt5.QtWidgets import QMainWindow, QAction, QMenu, QApplication

class Example(QMainWindow):

    def __init__(self):
        super().__init__()
        self.initUI()
    def initUI(self):
        menubar = self.menuBar()
        fileMenu = menubar.addMenu('File')

        impMenu = QMenu('Import', self)
        impAct = QAction('Import mail', self)
        impMenu.addAction(impAct)

        newAct = QAction('New', self)

        fileMenu.addAction(newAct)
        fileMenu.addMenu(impMenu)

        self.setGeometry(300, 300, 300, 200)
        self.setWindowTitle('Submenu')
        self.show()

def main():
    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()

在这里插入图片描述

用designer实现
在这里插入图片描述
在这里插入图片描述在这里插入图片描述

X、Y没法编辑,原因未知,虽然designer中显示 0,0
但是生成地代码中没有配置X,Y(默认显示在屏幕中央)
MainWindow.resize(300, 200)
在这里插入图片描述

主逻辑代码如下,几乎没有写啥。UI生成的代码为test3.py文件

import sys
from PyQt5.QtWidgets import QMainWindow, qApp, QMenu, QApplication
import test3

def main():
    app = QApplication(sys.argv)
    ex = QMainWindow()
    t=test3.Ui_MainWindow()
    t.setupUi(ex)
    ex.show()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()

check menu(**)

可以勾选的菜单,完全可以使用designer实现

import sys
from PyQt5.QtWidgets import QMainWindow, QAction, QApplication

class Example(QMainWindow):
    def __init__(self):
        super().__init__()
        self.initUI()


    def initUI(self):
        self.statusbar = self.statusBar()
        self.statusbar.showMessage('Ready')

        menubar = self.menuBar()
        viewMenu = menubar.addMenu('View')

        viewStatAct = QAction('View statusbar', self, checkable=True)
        viewStatAct.setStatusTip('View statusbar')
        viewStatAct.setChecked(True)
        viewStatAct.triggered.connect(self.toggleMenu)

        viewMenu.addAction(viewStatAct)

        self.setGeometry(300, 300, 300, 200)
        self.setWindowTitle('Check menu')
        self.show()

    def toggleMenu(self, state):
        if state:
            self.statusbar.show()
        else:
            self.statusbar.hide()

def main():
    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()

在这里插入图片描述

使用designer设计
在这里插入图片描述

再对应代码
viewStatAct.setStatusTip(‘View statusbar’)
配置QAction对象的statusTip属性
在这里插入图片描述
在这里插入图片描述

再对应代码
viewStatAct = QAction(‘View statusbar’, self, checkable=True)
viewStatAct.setChecked(True)

勾选checkable、checked
在这里插入图片描述

在这里插入图片描述

再定义槽toggleMenu(引线的时候可以自定义槽)
生成的代码有如下一行

self.actionNew.triggered.connect(MainWindow.toggleMenu)

完成designer部分的工作,designer中预览效果时,与目标还差一点,鼠标放到子目录上时还是会显示statusTip,接下来考逻辑部分来让它不显示
在这里插入图片描述

因为生成的UI代码中槽函数为MainWindow.toggleMenu,因此逻辑代码中需要继承MainWindow定义一个新类,并定义toggleMenu方法
但直接如下写会报错!

class Ex(QMainWindow):
    def toggleMenu(self, state):
        print(state)
        if state:
            self.statusbar.show()
        else:
            self.statusbar.hide()

但是!!!示例代码是把所有控件都定义为继承了MainWindow的类,因此可以直接self.statusbar
而使用designer生成的代码,控件是由UI代码中的类管理,与继承了MainWindow类是分开的
因此逻辑代码改写成如下

import sys
from PyQt5.QtWidgets import QMainWindow, qApp, QMenu, QApplication
import test3

t=test3.Ui_MainWindow()
class Ex(QMainWindow):
    def toggleMenu(self, state):
        if state:
            t.statusbar.show()
        else:
            t.statusbar.hide()

def main():
    app = QApplication(sys.argv)
    ex = Ex()
    #t=test3.Ui_MainWindow()
    t.setupUi(ex)
    ex.show()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()

context menu背景菜单(右键弹出来的)

在这里插入图片描述

Context menu 即右键点击出现的菜单

import sys
from PyQt5.QtWidgets import QMainWindow, qApp, QMenu, QApplication

class Example(QMainWindow):

    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        self.setGeometry(300, 300, 300, 200)
        self.setWindowTitle('Context menu')
        self.show()

    def contextMenuEvent(self, event):
        cmenu = QMenu(self)

        newAct = cmenu.addAction("New")
        openAct = cmenu.addAction("Open")
        quitAct = cmenu.addAction("Quit")
        action = cmenu.exec_(self.mapToGlobal(event.pos()))

        if action == quitAct:
            qApp.quit()

def main():
    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()

在这里插入图片描述
在这里插入图片描述

实现context menu,必须重定义QWidget类的contextMenuEvent方法!
类似于message box小节,重定义closeEvent来实现关闭控件前的动作,QWidget还有挺多xxxEvent方法,还可以进行更多样的控制

在这里插入图片描述

Event参数为一个事件,pos方法返回该事件发生的位置(以widget为坐标系的坐标),因此再使用QWidget的mapToGlobal方法来转换成以屏幕为坐标系的坐标
在这里插入图片描述
在这里插入图片描述

使用exec_方法(QWidget没有)来显示context menu

点击其中一个QAction对应的控件,exec_方法会返回对应的QAction,从而获知用户点击了啥
在这里插入图片描述

QToolbar控件

如果想直接点击目录栏就可以产生动作,而不是把action藏在子目录下(即对于那些很常用的命令),可以使用Toolbar控件
完全可以使用designer来实现,右键菜单可以看到添加Tool Bar的选项,还要添加/去除Status Bar,Menu Bar也可以去除的
在这里插入图片描述

但是在designer中找不到直接给Toolbar添加Action的方式。。。
但是可以在QMenu中创建好QAction控件,再拖动到Toolbar上!如下
在这里插入图片描述

在这里插入图片描述

import sys
from PyQt5.QtWidgets import QMainWindow, QAction, qApp, QApplication
from PyQt5.QtGui import QIcon

class Example(QMainWindow):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        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)

        self.setGeometry(300, 300, 300, 200)
        self.setWindowTitle('Toolbar')
        self.show()

def main():
    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()

在这里插入图片描述

定义一个QAction
在这里插入图片描述

toolbar对象是使用MainWindow对象的addToolBar方法来创建的!
(QWidget没有这个方法!!!)

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值