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没有这个方法!!!)