赞
踩
围棋讲究布局,房屋建筑讲究布局,布局是设计环节的一个重要组成部分,一个优秀的布局会让你的界面设计更具吸引力。在GUI设计布局时,需要考虑各种因素,其中元素的位置、分布占据重要角色。在QtDesinger中,有如下表所示几种布局。在设计时可以先拖拽布局方式至窗体当中再往布局中摆放控件,亦可以先在窗体中设计好控件再点击菜单栏布局方式或选中要布局的一些控件-右键-布局-布局方式。
布局方式 | 描述 |
水平布局 | 将控件水平排列于窗体或容器类组件中 |
垂直布局 | 将控件处置排列于窗体或容器类组件中 |
栅格布局 | 以行和列排列的单元格内放置控件 |
表单布局 | 用于创建两列表单,一般包含标签及输入 |
分裂器 | 左右或上下分割,用于自由改变大小的组件之间 |
上一期,我们讲述了PyQt5安装配置【2023 GUI设计如何学-PyQt5从入门到精通系列01-pycharm配置安装】。本次,我们将开启一个小项目练练手,基本功能是:单机打开文件,在QTableWidget里面展示数据;选择绘图类型,绘图展示,基本效果如下图所示。
控件及布局
QtDesigner可视化设计师为我们快速实现GUI设计。在此项目中,主要设计QFrame(一个基类,容器类控件,主要用来容纳一些控件并控制一些边框样式)、QGroupBox(个人最常用容器类控件)、QTableWidget(容器类控件,表格控件,用于表格设计或输出)及其布局(采用了水平布局、垂直布局、水平分裂器)
QAction设计
QAction类提供了抽象的用户界面Action,而这些Action可以被添加到菜单和工具栏中,并且可以自动保持在菜单和工具栏中的同步。QAction可以包括一个图标、菜单文本、快捷键、状态文本等。QAction被创建后拖拽到工具栏上,然后链接到实现相应action功能的槽函数上。
属性参数 | 描述 |
文本(Text) | Action的显示文字 |
对象名称(Object Name) | Action名称 |
ToolTip | 鼠标停留时显示的文字 |
Icon | 设置Action的图标 |
Checkable | 是否可以复选 |
Shortcut | 设置快捷键 |
部分代码展示
-
- import sys
-
- import qdarkstyle
- from PyQt5 import QtCore, QtGui, QtWidgets, sip
- from PyQt5.QtCore import Qt
- from PyQt5.QtGui import QFont
- from PyQt5.QtWidgets import QApplication, QWidget, QMainWindow, QTreeWidgetItem, QTableWidgetItem, QMessageBox, \
- QFileDialog
-
- import PlotWidgets
-
-
- class Ui_MainWindow(QMainWindow):
- def __init__(self):
- super(Ui_MainWindow, self).__init__()
- self.setupUi(self)
-
- def setupUi(self, MainWindow):
- MainWindow.setObjectName("MainWindow")
- MainWindow.resize(773, 747)
- self.centralwidget = QtWidgets.QWidget(MainWindow)
- self.centralwidget.setObjectName("centralwidget")
- self.horizontalLayout = QtWidgets.QHBoxLayout(self.centralwidget)
- self.horizontalLayout.setObjectName("horizontalLayout")
- self.frame = QtWidgets.QFrame(self.centralwidget)
- self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
- self.frame.setFrameShadow(QtWidgets.QFrame.Raised)
- self.frame.setObjectName("frame")
- self.frame_2 = QtWidgets.QFrame(self.frame)
- self.frame_2.setGeometry(QtCore.QRect(10, 10, 276, 581))
- self.frame_2.setFrameShape(QtWidgets.QFrame.StyledPanel)
- self.frame_2.setFrameShadow(QtWidgets.QFrame.Raised)
- self.frame_2.setObjectName("frame_2")
- self.verticalLayout = QtWidgets.QVBoxLayout(self.frame_2)
- self.verticalLayout.setObjectName("verticalLayout")
- self.groupBox = QtWidgets.QGroupBox(self.frame_2)
- self.groupBox.setObjectName("groupBox")
- self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.groupBox)
- self.verticalLayout_2.setObjectName("verticalLayout_2")
- self.radioButton = QtWidgets.QRadioButton(self.groupBox)
- self.radioButton.setObjectName("radioButton")
-
- self.verticalLayout_2.addWidget(self.radioButton)
- self.radioButton_2 = QtWidgets.QRadioButton(self.groupBox)
- self.radioButton_2.setObjectName("radioButton_2")
- self.radioButton_2.clicked.connect(self.plot1)
-
- self.verticalLayout_2.addWidget(self.radioButton_2)
- self.radioButton_3 = QtWidgets.QRadioButton(self.groupBox)
- self.radioButton_3.setObjectName("radioButton_3")
- self.verticalLayout_2.addWidget(self.radioButton_3)
- self.radioButton_4 = QtWidgets.QRadioButton(self.groupBox)
- self.radioButton_4.setObjectName("radioButton_4")
- self.verticalLayout_2.addWidget(self.radioButton_4)
- self.verticalLayout.addWidget(self.groupBox)
- self.tableWidget = QtWidgets.QTableWidget(self.frame_2)
- self.tableWidget.setObjectName("tableWidget")
- self.tableWidget.setColumnCount(0)
- self.tableWidget.setRowCount(0)
- self.verticalLayout.addWidget(self.tableWidget)
- self.horizontalLayout.addWidget(self.frame)
- MainWindow.setCentralWidget(self.centralwidget)
- self.statusbar = QtWidgets.QStatusBar(MainWindow)
- self.statusbar.setObjectName("statusbar")
- MainWindow.setStatusBar(self.statusbar)
- self.toolBar = QtWidgets.QToolBar(MainWindow)
- self.toolBar.setMinimumSize(QtCore.QSize(6, 44))
- self.toolBar.setObjectName("toolBar")
- MainWindow.addToolBar(QtCore.Qt.TopToolBarArea, self.toolBar)
- self.action_open = QtWidgets.QAction(MainWindow)
- self.action_open.setCheckable(True)
- self.action_open.setEnabled(True)
- icon = QtGui.QIcon()
- icon.addPixmap(QtGui.QPixmap("C:/Users/yanjiaxi/Pictures/微信截图_20230415215247.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
- self.action_open.setIcon(icon)
- self.action_open.setShortcutContext(QtCore.Qt.WindowShortcut)
- self.action_open.setObjectName("action_open")
- self.action_open.triggered.connect(self.load_data)
- self.action_save = QtWidgets.QAction(MainWindow)
- icon1 = QtGui.QIcon()
- icon1.addPixmap(QtGui.QPixmap("C:/Users/yanjiaxi/Pictures/微信截图_20230415215347.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
- self.action_save.setIcon(icon1)
- self.action_save.setObjectName("action_save")
- self.action_larger = QtWidgets.QAction(MainWindow)
- icon2 = QtGui.QIcon()
- icon2.addPixmap(QtGui.QPixmap("C:/Users/yanjiaxi/Pictures/下载.jpg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
- self.action_larger.setIcon(icon2)
- self.action_larger.setObjectName("action_larger")
- self.action_smaller = QtWidgets.QAction(MainWindow)
- icon3 = QtGui.QIcon()
- icon3.addPixmap(QtGui.QPixmap("C:/Users/yanjiaxi/Pictures/下载 (1).jpg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
- self.action_smaller.setIcon(icon3)
- self.action_smaller.setObjectName("action_smaller")
- self.toolBar.addAction(self.action_open)
- self.toolBar.addSeparator()
- self.toolBar.addAction(self.action_save)
- self.toolBar.addSeparator()
- self.toolBar.addAction(self.action_larger)
- self.toolBar.addSeparator()
- self.toolBar.addAction(self.action_smaller)
-
- self.curve = PlotWidgets.CurvesWidget()
- self.curve.setAutoFillBackground(True)
- self.horizontalLayout_8 = QtWidgets.QSplitter(self.frame)
- self.horizontalLayout_8.addWidget(self.frame_2)
- self.horizontalLayout_8.addWidget(self.curve)
-
- self.horizontalLayout_9 = QtWidgets.QVBoxLayout(self.frame)
- self.horizontalLayout_9.addWidget(self.horizontalLayout_8)
- # self.radioButton_2.clicked.connect(self.plot1)
- # self.rocCurveGraph.plotloocvcurve()
- self.retranslateUi(MainWindow)
- QtCore.QMetaObject.connectSlotsByName(MainWindow)
-
- def retranslateUi(self, MainWindow):
- _translate = QtCore.QCoreApplication.translate
- MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
- self.groupBox.setTitle(_translate("MainWindow", "作图类型"))
- self.radioButton.setText(_translate("MainWindow", "柱状图"))
- self.radioButton_2.setText(_translate("MainWindow", "折线图"))
- self.radioButton_3.setText(_translate("MainWindow", "饼图"))
- self.radioButton_4.setText(_translate("MainWindow", "极坐标图"))
- self.toolBar.setWindowTitle(_translate("MainWindow", "toolBar"))
- self.action_open.setText(_translate("MainWindow", "打开文件"))
- self.action_save.setText(_translate("MainWindow", "保存"))
- self.action_larger.setText(_translate("MainWindow", "放大"))
- self.action_smaller.setText(_translate("MainWindow", "缩小"))
-
- def load_data(self):
- import pandas as pd
- try:
- self.file, ok = QFileDialog.getOpenFileName(self, 'Open', './datas', 'Plan text (*.*)')
- train_Data = pd.read_csv(self.file,index_col = 0)
- input_table_rows = train_Data.shape[0]
- input_table_colunms = train_Data.shape[1]
- input_table_header = train_Data.columns.values.tolist()
-
- self.tableWidget.setColumnCount(input_table_colunms)
- self.tableWidget.setRowCount(input_table_rows)
- self.tableWidget.setHorizontalHeaderLabels(input_table_header)
-
- for i in range(len(train_Data.index)):
- for j in range(len(train_Data.columns)):
- self.tableWidget.setItem(i, j, QTableWidgetItem(str(train_Data.iloc[i, j])))
- except Exception as e:
- QMessageBox.critical(self, 'Error', str(e), QMessageBox.Ignore | QMessageBox.Reset, QMessageBox.Ignore)
- return self.file
-
- def plot1(self):
- if self.radioButton_2.isChecked() == True:
- sip.delete(self.curve)
- self.curve = PlotWidgets.CurvesWidget()
- self.horizontalLayout_8.addWidget(self.curve)
-
- self.curve.plotloocvcurve()
- pass
-
- if __name__ == '__main__':
- app = QApplication(sys.argv)
- app.setFont(QFont('Arial', 10))
- win = Ui_MainWindow()
- win.setStyleSheet(qdarkstyle.load_stylesheet_pyqt5())
- win.show()
- sys.exit(app.exec_())
总结
本小节,我们重点介绍了QtDesigner界面设计中的关键环节--布局,同时实现了一个简易的数据展示界面。通过此简易界面设计,掌握:布局、QAction、QGroupBox等容器控件的使用。针对绘图展示及其QAction槽函数关联,我们后续详细讲解。
更多内容,参考订阅号:数道
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。