PyQt笔记

本文介绍了使用PyQt构建用户界面的基本组件如按钮、输入框等,以及如何使用QLayout进行布局。上位机界面设计中提到如何在图片上添加控件,处理信号槽连接,使用QThread处理并发数据传输,以及展示了如何用QListWidget和QChart实现动态数据展示。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

基本UI

  • 按钮:qpushbutton
  • 文本:qlabel
  • 输入框:qlineedit
  • w.resize重新设置大小 w,move移动窗口位置
  • w.setwindowicon设置图标
  • QVBoxLayout是布局,添加弹簧addStretch
  • 三种窗口布局:qwidget自由度高啥都没有 qmianwindow包含菜单工具等,前一种的子类 qdialog对话框窗口基类
  • 信号和槽连接:对象->信号->connect(槽函数)
  • 自定义信号,pyqtsignal,需要放到__init__方法外面,类的里面
    • mysign = pyqtsignal
    • mysign.connect(槽函数)
    • 发送信号调用:mysign.emit
  • 先把显示不完的数据放到滚动对象,再把滚动对象放到布局器
上位机绘制
  1. 最好有别人的上位机图片,在图片上添加控件

    1. 去百度找,如果怕风险找公司设计部门的设计自己画

    2. 如果超级简单的上位机,就直接添加控件,拖上Layout整整就行

  2. 找到别人的上位机图片,在窗口插入一个List View

    1. styleSheet中输入background-image: url(“./template/system overview.png”),""中的是你图片的链接

    2. 将List View设置为底层

    3. 在图片的基础上插入控件,覆盖掉图片中的控件

      1. 默认栅格比较大,大小和位置不好对齐,打开窗体选项卡-窗体设定-栅格,将栅格距离改小为5
      2. 同时控件大小最好是栅格距离的整数倍
上位机编写
  1. 信号与槽,在文件中传递搞不太明白

    1. 建立一个Global文件,里面放需要传递的全局变量,其他文件调用Global.变量名进行传递
    2. 但是可能资源被竞争,导致不可控问题
  2. 数据发送、接收需要在不同线程中,否则会阻塞显示线程。

    1. 建立Send和Receive类,继承QThread类,其中关键是类中的run方法

    2. 当Send.start()会自动执行run方法,所以需要在run方法内写死循环,或者使能定时器后调用self.exec_()阻塞在里面,否则就只执行一遍

    3. 同理,主线程在调用.show后,也会sys.exit(app.exec_())

  3. 界面互相跳转,第一个类无法使用init方法初始化第二个类,所以需要单独写一个方法,在第二个类初始化后传入第一个类

  4. app.aboutToQuit.connect方法,会在关闭所有显示界面后调用一次,可以关联一些关闭操作

  5. 按钮比较简单一般只需要.clicked.connect,连接好点击后触发的操作即可

  6. spinbox可以直接在qt designer中,设置最大最小值,点击右侧按键的步长,有效减少了值判断工作量

    1. 获取框中的值,直接调用.value()就可以
  7. text browser缩小后不想显示滚动条,在ScrollArea中设置

    1. 显示值,直接调用.setText
  8. 解析DBC文件,安装cantools

  9. 显示折线图,先装PyQtChart,在界面中添加QListWidget,并调整好合适的大小

    1. 显示嵌套顺序:QListWidget->QListWidgetItem->QVBoxLayout->QChartView->QChart->QLineSeries
    2. 最好QChartView的大小根据item大小设定
    3. 显示关键代码如下所示
	# 主文件
	self.item_f = QListWidgetItem(self.P_listwidget_f)
        width, height = (
            self.P_listwidget_f.size().width(),
            self.P_listwidget_f.size().height(),
        )
        self.line_chart_widget_For = LineChartWidget(
            width,
            height
        )
        self.item_f.setSizeHint(self.line_chart_widget_For.sizeHint())
        self.P_listwidget_f.addItem(self.item_f)
        self.P_listwidget_f.setItemWidget(self.item_f, self.line_chart_widget_For)
        self.P_listwidget_f.setStyleSheet("QListWidget { border: none; }")
class LineChartWidget(QWidget):
	def initChart(self):
        self.series1 = QLineSeries() 
        self.series1.setName(self.line1name)
        self.chart = QChart() 
        self.chart.addSeries(self.series1)  
        self.chart.legend().setVisible(True)  # 显示图例
        self.chart.legend().setAlignment(Qt.AlignRight) 
        self.chart.legend().setContentsMargins(0, 0, 0, 0) 
        self.chart.legend().setSizePolicy(
            QSizePolicy.Minimum, QSizePolicy.Minimum
        ) 

        self.chart.setTitle(self.chart_title)  # 设置图表标题
        self.chart.createDefaultAxes()  # 创建默认坐标轴
        self.axis_x = self.chart.axisX()  
        self.axis_y = self.chart.axisY()

        self.axis_x.setLabelFormat("%i")  # 设置X轴标签数据类型
        self.axis_x.setTitleText(self.X_title)  # 设置X轴标题
        self.axis_y.setLabelFormat("%i")
        self.axis_y.setTitleText(self.Y_title)

        self.chart_view = QChartView(self.chart)  # 创建图表视图
        self.chart_view.setFixedSize(
            self.width + 40, self.height + 10
        )  # 设置图表视图大小
        
        self.chart_view.setContentsMargins(0, 0, 0, 0)  # 设置图表视图边距
        
		layout = QVBoxLayout(self)
        layout.addWidget(self.chart_view)
        layout.setSpacing(0)
        layout.setContentsMargins(0, 0, 0, 0)
        self.setLayout(layout)
  1. 数据显示,关键代码如下图所示

    1. data_queue1根据外部数据频率定期更新

    2. updateChart也一样,需要定期调用绘制曲线

def updateData(self):
        """
        更新数据到图表。
        """
        if not self.is_paused:
            self.x_value += 1
            # new_data_value1 = random.randint(1, 1000)
            self.data_queue1.append(self.new_data_value1)
            # new_data_value2 = random.randint(1, 1000)
            self.data_queue2.append(self.new_data_value2)
            self.updateChart()
def updateChart(self):
        min_x = self.x_value * 10 - self.max_x
        max_x = self.x_value * 10
        if min_x < 0:
            min_x = 0
            
        max_y = (
            max(max(self.data_queue1), max(self.data_queue2)) + 5
            if self.data_queue1 and self.data_queue2
            else 0
        )

        self.axis_x.setRange(min_x, max_x)  # 设置X轴范围
        self.axis_x.setTickCount(7)
        self.axis_y.setRange(0, max_y)  # 设置Y轴范围
        self.axis_y.setTickCount(7)
        self.series1.clear() 
        
        for i, (value1, value2) in enumerate(zip(self.data_queue1, self.data_queue2)):
            self.series1.append(i * 10, value1)  # 添加数据点到线系列1
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值