pyqt实战-软件通用界面设计模板样例

软件界面在这里插入图片描述

技术点

  • 无边框设计
  • 自定义右上角最大化,最小化,关闭按钮
  • 界面布局能够自适应界面的放大缩小
  • 按住鼠标左键能够拖动整个界面
  • treewidget整体风格设计
    在这里插入图片描述

代码

import sys

from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.Qt import *
import time
import os
import datetime

     

class Window(QWidget):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        """界面基本设置"""
        self.setWindowFlags(Qt.FramelessWindowHint)  # 设置了无边框的Flag
        self.resize(1920, 1080)
        self.move(400, 240)
        # self.setWindowOpacity(0.85)  # 设置不透明度
        # self.setWindowTitle("windowtitle")

        """主窗口水平布局,后面定义的控件才能显示"""
        self.horizontalLayout_window = QtWidgets.QHBoxLayout(self)
        self.horizontalLayout_window.setContentsMargins(1, 1, 1, 1)
        self.horizontalLayout_window.setSpacing(1)
        self.horizontalLayout_window.setObjectName("horizontalLayout_window")
        # self.setWindowIcon(QIcon("../Icons/snowflake_128px.ico"))

        """右上角三个功能按钮的参数"""
        self.top_margin = 1  # 三个按钮距离顶部的距离
        self.btn_w = 32  # 按钮宽度
        self.btn_h = 32  # 按钮高度

        """右上角三个功能按钮的图片路径"""
        self.BASE_DIR=os.path.dirname(sys.argv[0])
        self.close_path=self.BASE_DIR+'/resource/icon/close.png'
        self.max_path=self.BASE_DIR+'/resource/icon/max.png'
        self.min_path=self.BASE_DIR+'/resource/icon/min.png'
        self.restore_path=self.BASE_DIR+'/resource/icon/restore.png'

        self.setup_ui()

    def setup_ui(self):
        

        """在窗口的右上角添加关闭、最大化、最小化 三个按钮"""
        self.close_btn = QPushButton(self)  
        self.close_btn.setIcon(QIcon(self.close_path))
        self.close_btn.setIconSize(self.close_btn.iconSize())
        self.close_btn.resize(self.btn_w, self.btn_h)

        self.max_btn = QPushButton(self)  
        self.max_btn.setIcon(QIcon(self.max_path))
        self.max_btn.setIconSize(self.max_btn.iconSize())
        self.max_btn.resize(self.btn_w, self.btn_h)

        self.mini_btn = QPushButton(self)  
        self.mini_btn.setIcon(QIcon(self.min_path))
        self.mini_btn.setIconSize(self.mini_btn.iconSize())
        self.mini_btn.resize(self.btn_w, self.btn_h)

        # 监听按钮,连接信号与槽
        def max_normal():
            if self.isMaximized():
                self.max_btn.setIcon(QIcon(self.max_path))
                self.showNormal()
            else:
                self.showMaximized()
                self.max_btn.setIcon(QIcon(self.restore_path))
        
        self.max_btn.pressed.connect(max_normal)
        self.close_btn.pressed.connect(lambda: self.close())
        self.mini_btn.pressed.connect(lambda: self.showMinimized())

        """自定义treewidget滚动条样式"""
        def custom_scrollbar(widget):
            # 设置滚动条的样式
            # widget.setStyle(QStyleFactory.create('Fusion'))
        
            # 为滚动条设置样式
            scrollBar = widget.verticalScrollBar()
            # scrollBar = widget.horizontalScrollBar()
            scrollBar.setStyleSheet("""
            QScrollBar:vertical {
                border-width: 0px;
                border: none;
                background:rgba(64, 65, 79, 0);
                width:12px;
                margin: 0px 0px 0px 0px;
            }
            QScrollBar::handle:vertical {
                background: qlineargradient(x1:0, y1:0, x2:1, y2:0,
                stop: 0 #aaaaff, stop: 0.5 #aaaaff, stop:1 #aaaaff);
                min-height: 20px;
                max-height: 20px;
                margin: 0 0px 0 0px;
                border-radius: 6px;
            }
            QScrollBar::add-line:vertical {
                background: qlineargradient(x1:0, y1:0, x2:1, y2:0,
                stop: 0 rgba(64, 65, 79, 0), stop: 0.5 rgba(64, 65, 79, 0),  stop:1 rgba(64, 65, 79, 0));
                height: 0px;
                border: none;
                subcontrol-position: bottom;
                subcontrol-origin: margin;
            }
            QScrollBar::sub-line:vertical {
                background: qlineargradient(x1:0, y1:0, x2:1, y2:0,
                stop: 0  rgba(64, 65, 79, 0), stop: 0.5 rgba(64, 65, 79, 0),  stop:1 rgba(64, 65, 79, 0));
                height: 0 px;
                border: none;
                subcontrol-position: top;
                subcontrol-origin: margin;
            }
            QScrollBar::sub-page:vertical {
            background: rgba(64, 65, 79, 0);
            }

            QScrollBar::add-page:vertical {
            background: rgba(64, 65, 79, 0);
            }
            """
            )


        """设定widget_main"""
        self.widget_main = QtWidgets.QWidget(self)
        self.widget_main.setObjectName("widget_main")
        """widget_main定义水平布局"""
        self.horizontalLayout_widget_main = QtWidgets.QHBoxLayout(self.widget_main)
        self.horizontalLayout_widget_main.setContentsMargins(0, 0, 0, 0)
        self.horizontalLayout_widget_main.setSpacing(0)
        self.horizontalLayout_widget_main.setObjectName("horizontalLayout_widget_main")

        """widget_main中设定widget_left"""
        self.widget_left = QtWidgets.QWidget(self.widget_main)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(1)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.widget_left.sizePolicy().hasHeightForWidth())
        self.widget_left.setSizePolicy(sizePolicy)
        self.widget_left.setMaximumSize(QtCore.QSize(500, 16777215))
        self.widget_left.setStyleSheet("background-color: rgb(240, 243, 246);")
        self.widget_left.setObjectName("widget_left")
        """widget_left定义垂直布局"""
        self.verticalLayout_widget_left = QtWidgets.QVBoxLayout(self.widget_left)
        self.verticalLayout_widget_left.setObjectName("verticalLayout_widget_left")

        """widget_main中设定widget_right"""
        self.widget_right = QtWidgets.QWidget(self.widget_main)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(2)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.widget_right.sizePolicy().hasHeightForWidth())
        self.widget_right.setSizePolicy(sizePolicy)
        # self.widget_right.setStyleSheet("background-color: rgb(240, 243, 246);border:2px solid red;")
        self.widget_right.setObjectName("widget_right")
        """widget_right中定义垂直布局"""
        self.verticalLayout_widget_right = QtWidgets.QVBoxLayout(self.widget_right)
        self.verticalLayout_widget_right.setContentsMargins(0, 0, 0, 0)
        self.verticalLayout_widget_right.setSpacing(1)
        self.verticalLayout_widget_right.setObjectName("verticalLayout_widget_right")

        """widget_left中设定widget_left_top"""   
        self.widget_left_top = QtWidgets.QWidget(self.widget_left)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(1)
        sizePolicy.setHeightForWidth(self.widget_left_top.sizePolicy().hasHeightForWidth())
        # self.widget_left_top.setStyleSheet("background-color: rgb(240, 243, 246);border:2px solid red;")
        self.widget_left_top.setSizePolicy(sizePolicy)
        self.widget_left_top.setMaximumSize(QtCore.QSize(16777215, 150))
        self.widget_left_top.setObjectName("widget_left_top")

        """widget_right中设定软件标题"""   
        self.label_tool_name = QtWidgets.QLabel(self.widget_left_top)
        self.label_tool_name.setGeometry(QtCore.QRect(70, 10, 153, 19))
        self.label_tool_name.setStyleSheet("font: 75 13pt \"Arial\";")
        self.label_tool_name.setAlignment(QtCore.Qt.AlignCenter)
        self.label_tool_name.setObjectName("label_tool_name")
        self.label_tool_name.setText("音乐播放器")
        self.label_tool_name.adjustSize()

        self.label_tool_version = QtWidgets.QLabel(self.widget_left_top)
        self.label_tool_version.setGeometry(QtCore.QRect(130, 70, 24, 20))
        self.label_tool_version.setStyleSheet("font: 6pt \"Arial\";")
        self.label_tool_version.setAlignment(QtCore.Qt.AlignCenter)
        self.label_tool_version.setObjectName("label_tool_version")
        self.label_tool_version.setText("V1.0.1")
        self.label_tool_version.adjustSize()


        """widget_left中设定widget_left_bottom"""   
        self.widget_left_bottom = QtWidgets.QWidget(self.widget_left)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(4)
        sizePolicy.setHeightForWidth(self.widget_left_bottom.sizePolicy().hasHeightForWidth())
        self.widget_left_bottom.setSizePolicy(sizePolicy)
        self.widget_left_bottom.setObjectName("widget_left_bottom")
        self.horizontalLayout_widget_left_bottom = QtWidgets.QHBoxLayout(self.widget_left_bottom)
        # self.widget_left_bottom.setStyleSheet("background-color: rgb(240, 243, 246);border:2px solid red;")
        self.horizontalLayout_widget_left_bottom.setContentsMargins(0, 0, 0, 0)
        self.horizontalLayout_widget_left_bottom.setSpacing(0)
        self.horizontalLayout_widget_left_bottom.setObjectName("horizontalLayout_widget_left_bottom")


        """widget_left_bottom中设定treewidget"""  
        self.treeWidget_section = QtWidgets.QTreeWidget(self.widget_left_bottom)
        self.treeWidget_section.setStyleSheet("border:no;")
        self.treeWidget_section.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
        self.treeWidget_section.setObjectName("treeWidget_section")
        self.treeWidget_section.setColumnCount(1)  # 设置列数
        self.treeWidget_section.headerItem().setHidden(True)  # 隐藏头部项

        font = QtGui.QFont()
        font.setPointSize(13)

        self.treewidget_music= QTreeWidgetItem(self.treeWidget_section)
        self.treewidget_music.setText(0,'音乐')
        self.treewidget_music.setCheckState(0, Qt.Checked)
        self.treewidget_music.setFont(0, font)
        self.treewidget_music.setExpanded(True)

        self.treewidget_music_1_ = QTreeWidgetItem(self.treewidget_music)
        self.treewidget_music_1_.setText(0,'民谣')
        self.treewidget_music_2 = QTreeWidgetItem(self.treewidget_music)
        self.treewidget_music_2.setText(0,'流行')
        self.treewidget_music_3 = QTreeWidgetItem(self.treewidget_music)
        self.treewidget_music_3.setText(0,'怀旧')

        self.treewidget_collection= QTreeWidgetItem(self.treeWidget_section)
        self.treewidget_collection.setText(0,'收藏')
        self.treewidget_collection.setCheckState(0, Qt.Checked)
        self.treewidget_collection.setFont(0, font)
        self.treewidget_collection.setExpanded(True)

        self.treewidget_collection_1 = QTreeWidgetItem(self.treewidget_collection)
        self.treewidget_collection_1.setText(0,'周伦')
        self.treewidget_collection_1.setExpanded(True)

        self.treewidget_collection_1_1 = QTreeWidgetItem(self.treewidget_collection_1)
        self.treewidget_collection_1_1.setText(0,'1. 八里香')
        self.treewidget_collection_1_2 = QTreeWidgetItem(self.treewidget_collection_1)
        self.treewidget_collection_1_2.setText(0,'2. 半岛铝盒')
        self.treewidget_collection_1_3 = QTreeWidgetItem(self.treewidget_collection_1)
        self.treewidget_collection_1_3.setText(0,'3. 麦香')
        
        self.treewidget_collection_2 = QTreeWidgetItem(self.treewidget_collection)
        self.treewidget_collection_2.setText(0,'六月天')
        self.treewidget_collection_2.setExpanded(True)

        self.treewidget_collection_2_1 = QTreeWidgetItem(self.treewidget_collection_2)
        self.treewidget_collection_2_1.setText(0,'1. 不倔强')
        self.treewidget_collection_2_2 = QTreeWidgetItem(self.treewidget_collection_2)
        self.treewidget_collection_2_2.setText(0,'2. 不温柔')
        self.treewidget_collection_2_3 = QTreeWidgetItem(self.treewidget_collection_2)
        self.treewidget_collection_2_3.setText(0,'3. 离开土星表面')

        self.treewidget_setting= QTreeWidgetItem(self.treeWidget_section)
        self.treewidget_setting.setText(0,'设置')
        self.treewidget_setting.setCheckState(0, Qt.Checked)
        self.treewidget_setting.setFont(0, font)
        self.treewidget_setting.setExpanded(True)

        self.treewidget_setting_1 = QTreeWidgetItem(self.treewidget_setting)
        self.treewidget_setting_1.setText(0,'用户信息')
        self.treewidget_setting_1.setForeground(0,QColor(100,150,50))
        self.treewidget_setting_1.setExpanded(True)

        self.treewidget_setting_1_1 = QTreeWidgetItem(self.treewidget_setting_1)
        self.treewidget_setting_1_1.setText(0,'1. 基本信息')
        self.treewidget_setting_1_2 = QTreeWidgetItem(self.treewidget_setting_1)
        self.treewidget_setting_1_2.setText(0,'2. 头像')

        self.treewidget_setting_2 = QTreeWidgetItem(self.treewidget_setting)
        self.treewidget_setting_2.setText(0,'软件设置')
        self.treewidget_setting_2.setExpanded(True)

        self.treewidget_setting_2_1 = QTreeWidgetItem(self.treewidget_setting_2)
        self.treewidget_setting_2_1.setText(0,'1. 常规')
        self.treewidget_setting_2_2 = QTreeWidgetItem(self.treewidget_setting_2)
        self.treewidget_setting_2_2.setText(0,'2. 系统')

        """给treewidget设定自定义滚动条"""  
        custom_scrollbar(self.treeWidget_section)
        self.horizontalLayout_widget_left_bottom.addWidget(self.treeWidget_section)


        """widget_right中设定widget_right_top"""     
        self.widget_right_top = QtWidgets.QWidget(self.widget_right)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(2)
        sizePolicy.setHeightForWidth(self.widget_right_top.sizePolicy().hasHeightForWidth())
        # self.widget_right_top.setStyleSheet("background-color: rgb(240, 243, 246);border:2px solid red;")
        self.widget_right_top.setSizePolicy(sizePolicy)
        self.widget_right_top.setStyleSheet("background-color: rgb(247, 249, 252);")
        self.widget_right_top.setObjectName("widget_right_top")

        """widget_right_top中设定垂直布局"""    
        self.verticalLayout_widget_right_top = QtWidgets.QVBoxLayout(self.widget_right_top)
        self.verticalLayout_widget_right_top.setObjectName("verticalLayout_widget_right_top")

        self.label_latest = QtWidgets.QLabel(self.widget_right_top)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(1)
        sizePolicy.setHeightForWidth(self.label_latest.sizePolicy().hasHeightForWidth())
        self.label_latest.setSizePolicy(sizePolicy)
        self.label_latest.setStyleSheet("font: 75 13pt \"Arial\";")
        self.label_latest.setObjectName("label_latest")
        self.label_latest.setText(" 最新音乐")
        self.verticalLayout_widget_right_top.addWidget(self.label_latest)

        self.textEdit_latest = QtWidgets.QTextEdit(self.widget_right_top)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(10)
        sizePolicy.setHeightForWidth(self.textEdit_latest.sizePolicy().hasHeightForWidth())
        self.textEdit_latest.setSizePolicy(sizePolicy)
        self.textEdit_latest.setStyleSheet("font: 9pt \"Arial\";")
        self.textEdit_latest.setObjectName("textEdit_latest")
        self.verticalLayout_widget_right_top.addWidget(self.textEdit_latest)

        self.label_hot = QtWidgets.QLabel(self.widget_right_top)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(1)
        sizePolicy.setHeightForWidth(self.label_hot.sizePolicy().hasHeightForWidth())
        self.label_hot.setSizePolicy(sizePolicy)
        self.label_hot.setStyleSheet("font: 75 13pt \"Arial\";")
        self.label_hot.setObjectName("label_hot")
        self.label_hot.setText(" 热门推荐")
        self.verticalLayout_widget_right_top.addWidget(self.label_hot)


        self.textEdit_hot = QtWidgets.QTextEdit(self.widget_right_top)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(10)
        sizePolicy.setHeightForWidth(self.textEdit_hot.sizePolicy().hasHeightForWidth())
        self.textEdit_hot.setSizePolicy(sizePolicy)
        self.textEdit_hot.setStyleSheet("font: 9pt \"Arial\";")
        self.textEdit_hot.setObjectName("textEdit_hot")
        self.verticalLayout_widget_right_top.addWidget(self.textEdit_hot)

        """widget_right中设定widget_right_bottom"""   
        self.widget_right_bottom = QtWidgets.QWidget(self.widget_right)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(1)
        # self.widget_right_bottom.setStyleSheet("background-color: rgb(240, 243, 246);border:2px solid red;")
        sizePolicy.setHeightForWidth(self.widget_right_bottom.sizePolicy().hasHeightForWidth())
        self.widget_right_bottom.setSizePolicy(sizePolicy)
        self.widget_right_bottom.setMaximumSize(QtCore.QSize(16777215, 300))
        self.widget_right_bottom.setStyleSheet("background-color: rgb(247, 249, 252);")
        self.widget_right_bottom.setObjectName("widget_right_bottom")

        self.label_operation = QtWidgets.QLabel(self.widget_right_bottom)
        self.label_operation.setGeometry(QtCore.QRect(18, 0, 151, 41))
        self.label_operation.setStyleSheet("font: 75 13pt \"Arial\";")
        self.label_operation.setObjectName("label_operation")
        self.label_operation.setText("Operation")
        self.label_operation.adjustSize()

        font_operation = QtGui.QFont()
        font_operation.setFamily("Arial")

        self.pushButton_play = QtWidgets.QPushButton(self.widget_right_bottom)
        self.pushButton_play.setGeometry(QtCore.QRect(80, 120, 200, 60))
        self.pushButton_play.setStyleSheet("QPushButton{color: #606266;background-color: #fff; border: 1px solid #dcdfe6;}\n"
                                            "QPushButton:hover{color: #409eff;border-color: #c6e2ff;background-color: #ecf5ff}\n"
                                            "QPushButton:checked{color: #409eff;border-color: #c6e2ff;background-color: #ecf5ff;}\n"
                                            "QPushButton:pressed{color: #3a8ee6;border-color: #3a8ee6;background-color: #ecf5ff;}\n"
                                            "")
        self.pushButton_play.setText('播放')
        self.pushButton_play.setObjectName("pushButton_play")
        self.pushButton_next = QtWidgets.QPushButton(self.widget_right_bottom)
        self.pushButton_next.setGeometry(QtCore.QRect(620, 120, 200, 60))
        self.pushButton_next.setStyleSheet("QPushButton{color: #606266;background-color: #fff; border: 1px solid #dcdfe6;}\n"
                                            "QPushButton:hover{color: #409eff;border-color: #c6e2ff;background-color: #ecf5ff}\n"
                                            "QPushButton:checked{color: #409eff;border-color: #c6e2ff;background-color: #ecf5ff;}\n"
                                            "QPushButton:pressed{color: #3a8ee6;border-color: #3a8ee6;background-color: #ecf5ff;}\n"
                                            "")
        self.pushButton_next.setText('下一首')
        self.pushButton_next.setObjectName("pushButton_next")

        self.pushButton_play.setFont(font_operation)
        self.pushButton_next.setFont(font_operation)
        self.pushButton_next.setEnabled(False)

        self.comboBox_list = QtWidgets.QComboBox(self.widget_right_bottom)
        self.comboBox_list.setGeometry(QtCore.QRect(350, 120, 200, 60))
        self.comboBox_list.setFont(font_operation)
        self.comboBox_list.setStyleSheet(" QComboBox {\n"
"                border: 1px solid #C2C7CB;\n"
"                border-radius: 4px;\n"
"                padding: 1px 18px 1px 3px;\n"
"                background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,\n"
"                                                 stop: 0 #F7F7F7, stop: 1 #E3E3E3);\n"
"            }\n"
"            QComboBox::drop-down {\n"
"                subcontrol-origin: padding;\n"
"                subcontrol-position: top right;\n"
"                width: 20px;\n"
"                border-left-width: 1px;\n"
"                border-left-color: darkgray;\n"
"                border-left-style: solid;\n"
"                background-color: #D2D7D3;\n"
"            }\n"
# "            QComboBox::down-arrow {\n"
# "                image: url(C:/Users/xt2/Downloads/down_arrow.png);\n"
# "            }\n"
"            QComboBox::editable {\n"
"                background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,\n"
"                                                 stop: 0 #F7F7F7, stop: 1 #E3E3E3);\n"
"            }")
        self.comboBox_list.setObjectName("comboBox_list")
        self.comboBox_list.addItem("播放列表")
        self.comboBox_list.addItem("播放列表1")
        self.comboBox_list.addItem("播放列表2")
        


        self.horizontalLayout_window.addWidget(self.widget_main)
        self.horizontalLayout_widget_main.addWidget(self.widget_left)
        self.horizontalLayout_widget_main.addWidget(self.widget_right)
        self.verticalLayout_widget_left.addWidget(self.widget_left_top)
        self.verticalLayout_widget_left.addWidget(self.widget_left_bottom)
        self.verticalLayout_widget_right.addWidget(self.widget_right_top)
        self.verticalLayout_widget_right.addWidget(self.widget_right_bottom)


        """右上角最大,最小,还原三个按钮置顶"""
        self.close_btn.raise_()
        self.max_btn.raise_()
        self.mini_btn.raise_()


    def resizeEvent(self, a0: QtGui.QResizeEvent) -> None:
        """当窗口大小改变时,重新移动三个按钮的位置"""
        self.close_btn.move(self.width() - self.btn_w, self.top_margin)
        self.max_btn.move(self.width() - self.btn_w * 2, self.top_margin)
        self.mini_btn.move(self.width() - self.btn_w * 3, self.top_margin)


    def mousePressEvent(self, evt):
        # print("鼠标按下")
        if evt.button() == Qt.LeftButton:  # 仅在鼠标左键按下时可以拖动
            self.move_flag = True  # 设置一个标记,确保只有在执行 mousePressEvent之后才会执行 mouseMoveEvent
            # 确定两个点(鼠标第一次按下的点,窗口当前所在的原始点)
            self.mouse_x = evt.globalX()
            self.mouse_y = evt.globalY()
            # print(self.mouse_x, self.mouse_y)
            self.origen_x = self.x()
            self.origen_y = self.y()

    def mouseMoveEvent(self, evt) -> None:
        if self.move_flag:
            # print(evt.globalX(), evt.globalY())
            # 计算的是移动向量
            move_x = evt.globalX() - self.mouse_x
            move_y = evt.globalY() - self.mouse_y
            dest_x = self.origen_x + move_x
            dest_y = self.origen_y + move_y
            self.move(dest_x, dest_y)

    def mouseReleaseEvent(self, a0: QtGui.QMouseEvent) -> None:
        self.move_flag = False  # 鼠标释放后重置标记,避免无法释放拖动

app = QApplication(sys.argv)

window = Window()
window.show()

sys.exit(app.exec_())

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/547886.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

c# 服务创建

服务 创建服务 编写服务 可以对server1.cs重新命名,点击你的server按F7进入代码编辑模式,编写脚本 双击你的server.cs右击空白位置,添加安装程序,此时会生成“serviceInstaller1”及“serviceProcessInstaller1” 后续可以点击P…

开源相机管理库Aravis例程学习(一)——单帧采集single-acquisition

开源相机管理库Aravis例程学习(一)——单帧采集single-acquisition 简介源码函数说明arv_camera_newarv_camera_acquisitionarv_camera_get_model_namearv_buffer_get_image_widtharv_buffer_get_image_height 简介 本文针对官方例程中的第一个例程&…

CSS特效---跳动的文字

1、演示 2、一切尽在代码中 <!--* Author: your name* Date: 2023-10-03 14:42:44* LastEditTime: 2023-10-03 14:56:26* LastEditors: DESKTOP-536UVPC* Description: In User Settings Edit* FilePath: \css-special-effects\跳动的文字.html --> <!DOCTYPE html>…

【Linux】进程的优先级环境变量

个人主页 &#xff1a; zxctscl 如有转载请先通知 文章目录 1. 前言2. 进程的优先级2.1 什么是优先级2.2 为什么要有优先级2.3 优先级的查看方式2.4 对优先级调整 3. 命令行参数4. 环境变量4.1 环境变量与配置文件4.1.1 环境变量初步介绍4.1.2 配置文件 4.2 更多环境变量4.3 整…

Shiro整合EhCache缓存(二)

Shiro整合EhCache缓存 1、授权、角色认证1.1、后端接口服务注解1.2、授权-获取角色1.3、授权-获取权限1.4、授权-异常处理1.5、前端页面授权 2、EhCache2.1、Shiro整合EhCache 1、授权、角色认证 用户登录后&#xff0c;需要验证是否具有指定角色指定权限。Shiro也提供了方便的…

企业网络日益突出的难题与SD-WAN解决方案

随着企业规模的迅速扩张和数字化转型的深入推进&#xff0c;企业在全球范围内需要实现总部、分支机构、门店、数据中心、云等地点的网络互联、数据传输和应用加速。SD-WAN作为当今主流解决方案&#xff0c;在网络效率、传输质量、灵活性和成本等方面远远超越传统的互联网、专线…

归并排序详解(附代码)

归并排序 数据科学家每天都在处理算法。 然而&#xff0c;数据科学学科作为一个整体已经发展成为一个不涉及复杂算法实现的角色。 尽管如此&#xff0c;从业者仍然可以从建立对算法的理解和知识库中受益。 在本文中&#xff0c;对排序算法归并排序进行了介绍、解释、评估和实…

高温超导量子干涉仪更具实用价值 政策推动行业研制能力提升

高温超导量子干涉仪更具实用价值 政策推动行业研制能力提升 高温超导量子干涉仪&#xff0c;一种采用临界温度在77K以上高温超导材料制造而成的可对磁场微小变化进行测量的仪器&#xff0c;需要工作在液氮环境中。 超导量子干涉仪&#xff08;SQUID&#xff09;&#xff0c;一种…

面试官:为什么忘记密码要重置而不是告诉你原密码?

这是一个挺有意思的面试题,挺简单的,不知道大家平时在重置密码的时候有没有想过这个问题。回答这个问题其实就一句话:因为服务端也不知道你的原密码是什么。如果知道的话,那就是严重的安全风险问题了。 我们这里来简单分析一下。 做过开发的应该都知道,服务端在保存密码到…

CPLD可运行的最高频率是多少

CPLD可运行的最高频率是多少 AG32 内置CPLD的可运行最高频率 AG32 内置CPLD的可运行最高频率 AG32 MCU 的运行最高频率是248M。而CPLD中没有标准的最高频率。 最大能跑多少MHz&#xff0c;取决于cpld 里的设计。 如果是逻辑电路&#xff0c;则不存在时钟的概念。 如果是时序电路…

在vue和 js 、ts 数据中使用 vue-i18n,切换语言环境时,标签文本实时变化

我的项目需要显示两种语言(中文和英文)&#xff0c;并且我想要切换语言时&#xff0c;页面语言环境会随之改变&#xff0c;目前发现&#xff0c;只能在vue中使用$t(‘’)的方式使用&#xff0c;但是这种方式只能在vue中使用&#xff0c;而我的菜单文件是定义在js中&#xff0c;…

直流充电桩与交流充电桩有哪些区别,如何选最靠谱?

在当今快速发展的电动汽车市场&#xff0c;正确选择充电桩成为了车主们面临的重要问题之一。直流充电桩与交流充电桩区到底有什么区别&#xff1f;哪些方面不同&#xff1f;分别适用场景是什么&#xff1f;不同场景应该怎么选&#xff1f;本文一文为您详解。 一、直流充电桩与交…

ObjectMapper的具体介绍与使用

文章目录 声明一、前言二、ObjectMapper与JSONObject比较1、核心主要有三个部分&#xff1a;依赖包不同 2、ObjectMapper使用概述2.1、工程的pom.xml导包信息2.2、创建案例中的测试对象2.3、对象和JSON相互转化2.3.1、测试代码2.3.2、测试结果展示 2.4、集合和JSON像话转化2.4.…

【让自己的U盘变得与众不同】

文章目录 今日座右铭&#xff1a;在心里种花&#xff0c;人生才不会荒芜。 文章目录 文章目录前言一、准备ICO图标二、插入U盘1.点击新建文本文档-输入代码-点击保存2.将代码文本文档名称修改为autorun.inf在这里插入图片描述3.将图标及代码文本文档放入U盘中在这里插入图片描述…

深度残差收缩网络中,使用 Sigmoid 函数的用意在哪?

在深度残差收缩网络中&#xff0c;使用 Sigmoid 函数将输出归一化到 0 和 1 之间的目的是为了限制输出值的范围&#xff0c;并且使得输出可以被解释为概率。这个 Sigmoid 函数的输出可以被看作是一个置信度或者概率的度量&#xff0c;表示某个事件发生的可能性。 在设置阈值时…

财富池指标--通达信主力建仓免费指标公式源码

主力交易一只个股&#xff0c;一般会经过以下几个阶段&#xff1a;建仓、拉升、出货。那么&#xff0c;怎么判断一只股票正处于主力建仓时期呢&#xff1f; 1、从k线图上来看 个股走势图中&#xff0c;连续出现小阳线的k线图&#xff0c;其成交量持续放量&#xff0c;或者在个…

【学习笔记】rt-thread

任务 创建好任务&#xff0c;不管是动态还是静态创建&#xff0c;任务的状态是init &#xff0c;通过start方法来启动任务&#xff1b;线程大小 设置小了&#xff0c;无法正常工作&#xff1f;显示占空间100% 启动过程 TODO 这是编译器特性&#xff1f; 因为RT-Thread使用编…

【QT+QGIS跨平台编译】181:【QGIS+Qt跨平台编译】—【错误处理:找不到_DEBUGA】

点击查看专栏目录 文章目录 一、找不到_DEBUGA二、原因分析三、错误处理 一、找不到_DEBUGA 报错信息&#xff1a; 二、原因分析 采用了非UNICODE&#xff1a; DEFINES - UNICODE没法识别 _DEBUGA 但可以识别 _DEBUG 三、错误处理 修改 _DEBUGA 为 _DEBUG

Android13 开机时间优化

前言 实际生活当中&#xff0c;针对某些应用场景&#xff0c;对Android启动时间要求比较严格&#xff0c;比如车载&#xff0c;车都开出去几公里了&#xff0c;IVI系统还没起来&#xff0c;这就比较尴尬&#xff0c;所以&#xff0c;优化Android启动时间是一项非常重要的工作。…

windows Nginx上部署若依后台管理登录界面之验证码不显示

大多数情况都是本地电脑Nginx部署正常&#xff0c;服务器Nginx部署验证码不显示。如下图 其实是Nginx配置有问题 server {listen 80;//监听端口server_name 域名或者公网ip等;location / {root D:/dist;//前端包文件路径需要修改index index.html; //不用管try_files …