• 【PyQt5图形界面编程(4)】:界面开发


    需求

    开发一个界面,用于配置具体功能属性,最终生成自己想要的c代码。

    具体要求:

    • 左侧是具体大类栏,如:IO,ADC,PWW
    • 右侧为具体属性栏,如:名称,…
    • 选择某一具体条目时,显示对应的属性配置
      实现的效果:以Davinci为例
      在这里插入图片描述

    涉及用到模块:

    • QMenuBar
    • QMenu
    • QAction
    • QTreeWidget
    • QStackedWidget
    • QWidget
    • QLable
    • QLineEdit
    • QXomboBox(下拉盒)
    • Frame

    开发思路

    • 图形开发基本是置顶而下的,从顶层往下设计
    • 代码开发也借鉴图形开发方式,采用继承方式,逐一往下开发
    • 为了便于开发,可以采用qt designer和代码开发这两者方式结合开发
      图形用于调整界面,代码用于方便补充内容

    开发过程

    在这里插入图片描述
    实现方法:

    • 1、当单击左边的QTreeWidget时
    • 2、处理单击事件:获取当前行,并调用setCurrentIndex来显示QStackedWidget具体窗口
    • 3、可以采用QFormLayout属性,在QStackedWidget窗口内可以添加具体内容
    • 4、QFormLayout是垂直布局属性(QVBoxLayout),便于软件逐行添加,执行formLayout.addRow(“名称”,“…”)

    QTreeWidget

    创建QTreeWidget(树形窗口)

    	self.youSelf_QTreeWidget = QtWidgets.QTreeWidget(被继承的窗口)
    
    • 1

    创建Item(条目)

    创建Item

        item_1 = QtWidgets.QTreeWidgetItem(self.youSelf_QTreeWidget)#创建1级条目
        item_11 = QtWidgets.QTreeWidgetItem(item_0 )#1级条目下再创建2级条目 
        item_111 = QtWidgets.QTreeWidgetItem(item_11 )#1级条目下的2级条目下创建3级条目  
    
    • 1
    • 2
    • 3

    问题

    1、item文本如果过长,显示不完全,出现省略号

    在这里插入图片描述
    解决方法:
    加大MinimumSectionSize的值,比如100等
    在这里插入图片描述
    参考:PyQt5中设置QtreeWidget水平滚动条

    开发

    1、获取当前鼠标选中的行,进而显示对应的属性
    class Ui_MainWindow(object):
        def setupUi(self, MainWindow):
        '''
        #....
        '''
    	 	self.IOHW_QTreeWidget.clicked.connect(self.onClicked)
    
    
        def onClicked(self):
            item = self.IOHW_QTreeWidget.currentItem()
            if item.parent():#它的父类存在
                print(item.text(0))#自己的内容
                print(item.parent().text(0))
                if item.parent().text(0) == "IO":
                    self.stackedWidget.setCurrentIndex(self.stackedWidget.indexOf(self.page_IO))
                if item.parent().text(0) == "ADC":
                    self.stackedWidget.setCurrentIndex(self.stackedWidget.indexOf(self.page_ADC))
                if item.parent().text(0) == "PWM":
                    self.stackedWidget.setCurrentIndex(self.stackedWidget.indexOf(self.page_PWM))
                if item.parent().text(0) == "test":
                    self.stackedWidget.setCurrentIndex(self.stackedWidget.indexOf(self.page_test))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    引用

    PyQt5.QtWidgets.QFormLayout:窗体布局

    PyQt5.QtWidgets.QFormLayout

    QStackedWidget:堆栈窗体

    • 插入窗体
      在这里插入图片描述

    • 在堆栈窗体的某一窗体内放入布局窗体(QFormLayout),并设置成垂直布局(QVBoxLayout)
      在这里插入图片描述
      在这里插入图片描述

    • 窗体相关生成的代码:

            self.page_test = QtWidgets.QWidget()			#1、创建的窗体page_test
            self.page_test.setObjectName("page_test")
            self.verticalLayout_page_test = QtWidgets.QVBoxLayout(self.page_test)	#2、将page_test窗体设置成垂直布局
            self.verticalLayout_page_test.setObjectName("verticalLayout_page_test")
            self.formLayout_page_test = QtWidgets.QFormLayout()		#3、创建布局
            self.formLayout_page_test.setObjectName("formLayout_page_test")
            self.verticalLayout_page_test.addLayout(self.formLayout_page_test)		#4、将布局添加到垂直布局中
            self.stackedWidget.addWidget(self.page_test)	#5、将page_test窗体添加到堆栈窗体内
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    效果:
    在这里插入图片描述

    • 手动添加的代码,补充内容
            '''
            # 手动添加,方便开发
            '''
            # 在page_test中添加行编辑器
            self.page_test.edit1 = QtWidgets.QLineEdit()#定义
            self.formLayout_page_test.addRow('整数校验', self.page_test.edit1)#添加
    
            # 在page_test中添加下拉编辑器
            self.page_test.combo_box = QtWidgets.QComboBox()#定义
            self.page_test.combo_box.addItems(['Option1', 'Option2', 'Option3'])#下拉值
            self.formLayout_page_test.addRow('整数校验2', self.page_test.combo_box)#添加
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    垂直布局选择与否

    • 选择了垂直布局效果
      在这里插入图片描述
    • 未选择垂直布局效果
      在这里插入图片描述

    PyQt5.QtCore.QSettings()

    PyQt5.QtCore.QSettings()

    总结

    • 用Qt Designer每次更新UI再用PyUic更新成.py文件时,.py文件总是覆盖自己添加的代码
      解决方法就是用继承父类的方法,采用继承方法
      python类的继承

    数据保存及打开Qsetting

    PyQt学习笔记-使用QSettings保存系统配置参数

    QListWidget、QTableWidget将所选项目保存到Qsettings

    aaa
    以下是转载

    import contextlib
    from PyQt5 import QtCore, QtGui, QtWidgets
    
    
    class SettingsManager:
        def __init__(self, filename):
            self.m_settings = QtCore.QSettings(filename, QtCore.QSettings.IniFormat)
    
        @property
        def settings(self):
            return self.m_settings
    
        def read(self, widget):
            self.settings.beginGroup(widget.objectName())
            if isinstance(widget, QtWidgets.QAbstractItemView):
                selectionMode = self.settings.value(
                    "selectionMode", type=QtWidgets.QAbstractItemView.SelectionMode
                )
                widget.setSelectionMode(selectionMode)
            if isinstance(widget, QtWidgets.QListWidget):
                items = self.settings.value("items")
                selecteditems = self.settings.value("selecteditems")
                # In the first reading the initial values must be established
                if items is None:
                    self.read_defaults(widget)
                else:
                    stream = QtCore.QDataStream(items, QtCore.QIODevice.ReadOnly)
                    while not stream.atEnd():
                        it = QtWidgets.QListWidgetItem()
                        stream >> it
                        widget.addItem(it)
                    stream = QtCore.QDataStream(
                        selecteditems, QtCore.QIODevice.ReadOnly
                    )
                    while not stream.atEnd():
                        row = stream.readInt()
                        it = widget.item(row)
                        if it is not None:
                            it.setSelected(True)
            if isinstance(widget, QtWidgets.QTableWidget):
                rowCount = self.settings.value("rowCount", type=int)
                columnCount = self.settings.value("columnCount", type=int)
                widget.setRowCount(rowCount)
                widget.setColumnCount(columnCount)
                items = self.settings.value("items")
                if items is None:
                    self.read_defaults(widget)
                else:
                    stream = QtCore.QDataStream(items, QtCore.QIODevice.ReadOnly)
                    while not stream.atEnd():
                        it = QtWidgets.QTableWidgetItem()
                        i = stream.readInt()
                        j = stream.readInt()
                        stream >> it
                        widget.setItem(i, j, it)
                    selecteditems = self.settings.value("selecteditems")
                    stream = QtCore.QDataStream(
                        selecteditems, QtCore.QIODevice.ReadOnly
                    )
                    while not stream.atEnd():
                        i = stream.readInt()
                        j = stream.readInt()
                        it = widget.item(i, j)
                        if it is not None:
                            it.setSelected(True)
            self.settings.endGroup()
    
        def write(self, widget):
            self.settings.beginGroup(widget.objectName())
            if isinstance(widget, QtWidgets.QAbstractItemView):
                self.settings.setValue("selectionMode", widget.selectionMode())
            if isinstance(widget, QtWidgets.QListWidget):
                items = QtCore.QByteArray()
                stream = QtCore.QDataStream(items, QtCore.QIODevice.WriteOnly)
                for i in range(widget.count()):
                    stream << widget.item(i)
                self.settings.setValue("items", items)
                selecteditems = QtCore.QByteArray()
                stream = QtCore.QDataStream(
                    selecteditems, QtCore.QIODevice.WriteOnly
                )
                for it in widget.selectedItems():
                    stream.writeInt(widget.row(it))
    
                self.settings.setValue("selecteditems", selecteditems)
            if isinstance(widget, QtWidgets.QTableWidget):
                self.settings.setValue("rowCount", widget.rowCount())
                self.settings.setValue("columnCount", widget.columnCount())
                items = QtCore.QByteArray()
                stream = QtCore.QDataStream(items, QtCore.QIODevice.WriteOnly)
                for i in range(widget.rowCount()):
                    for j in range(widget.columnCount()):
                        it = widget.item(i, j)
                        if it is not None:
                            stream.writeInt(i)
                            stream.writeInt(j)
                            stream << it
                self.settings.setValue("items", items)
                selecteditems = QtCore.QByteArray()
                stream = QtCore.QDataStream(
                    selecteditems, QtCore.QIODevice.WriteOnly
                )
                for it in widget.selectedItems():
                    # print(it.row(), it.column())
                    stream.writeInt(it.row())
                    stream.writeInt(it.column())
                self.settings.setValue("selecteditems", selecteditems)
            self.settings.endGroup()
    
        def release(self):
            self.m_settings.sync()
    
        def read_defaults(self, widget):
            if widget.objectName() == "listwidget_1":
                widget.setSelectionMode(QtWidgets.QAbstractItemView.MultiSelection)
                for i in range(10):
                    widget.addItem(QtWidgets.QListWidgetItem(str(i)))
            elif widget.objectName() == "listwidget_2":
                widget.setSelectionMode(QtWidgets.QAbstractItemView.MultiSelection)
                for i in "abcdefghijklmnopqrstuvwxyz":
                    widget.addItem(QtWidgets.QListWidgetItem(i))
            elif widget.objectName() == "tablewidget":
                widget.setSelectionMode(QtWidgets.QAbstractItemView.MultiSelection)
                widget.setRowCount(10)
                widget.setColumnCount(10)
                for i in range(widget.rowCount()):
                    for j in range(widget.columnCount()):
                        it = QtWidgets.QTableWidgetItem("{}-{}".format(i, j))
                        widget.setItem(i, j, it)
    
    
    @contextlib.contextmanager
    def settingsContext(filename):
        manager = SettingsManager(filename)
        try:
            yield manager
        finally:
            manager.release()
    
    
    class Widget(QtWidgets.QWidget):
        def __init__(self, parent=None):
            super().__init__(parent)
    
            self.listwidget_1 = QtWidgets.QListWidget(objectName="listwidget_1")
            listwidget_2 = QtWidgets.QListWidget(objectName="listwidget_2")
    
            tablewidget = QtWidgets.QTableWidget(objectName="tablewidget")
    
            lay = QtWidgets.QVBoxLayout(self)
            lay.addWidget(self.listwidget_1)
            lay.addWidget(listwidget_2)
            lay.addWidget(tablewidget)
    
            self.read_settings()
    
        def closeEvent(self, event):
            self.write_settings()
            super().closeEvent(event)
    
        def read_settings(self):
            with settingsContext("data.ini") as m:
                for children in self.findChildren(QtWidgets.QWidget):
                    if children.objectName():
                        m.read(children)
    
        def write_settings(self):
            with settingsContext("data.ini") as m:
                for children in self.findChildren(QtWidgets.QWidget):
                    if children.objectName():
                        m.write(children)
    
    
    if __name__ == "__main__":
        import sys
    
        app = QtWidgets.QApplication(sys.argv)
        w = Widget()
        w.resize(640, 480)
        w.show()
        sys.exit(app.exec_())
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
  • 相关阅读:
    go get命令不再具有安装功能
    JVM简介
    Python基础之dict和set的使用
    Ground Truth
    循环结构 ----- for/in 语句 与 for/of语句
    java实用代码-----HttpsUtil
    【CSDN 每日一练 ★☆☆】【蛮力/双指针】删除排序链表中的重复元素
    C#面:.NET Remoting 的⼯作原理是什么
    一阶滞后低通滤波器(支持采样频率设置 博途SCL代码)
    java自习室管理系统计算机毕业设计MyBatis+系统+LW文档+源码+调试部署
  • 原文地址:https://blog.csdn.net/tanjinyi912709177912/article/details/133773588