PyQt5从入门到精通系列02-布局(数据展示GUI小项目)

围棋讲究布局,房屋建筑讲究布局,布局是设计环节的一个重要组成部分,一个优秀的布局会让你的界面设计更具吸引力。在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槽函数关联,我们后续详细讲解。

更多内容,参考订阅号:数道

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值