PyQt:【重磅干货】实现一个自定义样式的窗口(比如去掉边框、改变标题位置、窗口按钮样式)

如果想突破PyQt自带窗口的样式限制,比如同时去掉窗口的边框、改变边框、改变标题位置、窗口控制按钮等等,那就需要实现一个自定义样式的窗口,本文教你如何实现

先来看看PyQt创建窗口的默认样式:

在这里插入图片描述

再看看一个自定义样式的窗口:

在这里插入图片描述

可以看到,这里示例的自定义窗口去掉了窗口的边框、改变了标题位置、标题栏颜色、窗口控制按钮的样式、去掉了最大化按钮

上完整代码:


#-*- coding:utf-8 -*-

from PyQt5.QtWidgets import QWidget, QLabel, QPushButton, QVBoxLayout
from PyQt5.QtCore import Qt, QPoint
from PyQt5.QtGui import QFont, QCursor

class QTitleLabel(QLabel):
  """
  新建标题栏标签类
  """
  def __init__(self, *args):
    super(QTitleLabel, self).__init__(*args)
    self.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)
    self.setFixedHeight(30)

class QTitleButton(QPushButton):
  """
  新建标题栏按钮类
  """
  def __init__(self, *args):
    super(QTitleButton, self).__init__(*args)
    self.setFont(QFont("Webdings")) # 特殊字体以不借助图片实现最小化最大化和关闭按钮
    self.setFixedWidth(40)

class QUnFrameWindow(QWidget):
  """
  无边框窗口类
  """
  def __init__(self):
    super(QUnFrameWindow, self).__init__(None, Qt.FramelessWindowHint) # 设置为顶级窗口,无边框
    self._padding = 5 # 设置边界宽度为5
    self.setGeometry(100, 100, 400, 300)
    self.initTitleLabel() # 安放标题栏标签
    self.setWindowTitle = self._setTitleText(self.setWindowTitle) # 用装饰器将设置WindowTitle名字函数共享到标题栏标签上
    self.setWindowTitle("自定义窗口")
    self.initLayout() # 设置框架布局
    self.setMinimumWidth(250)
    self.setMouseTracking(True) # 设置widget鼠标跟踪
    self.initDrag() # 设置鼠标跟踪判断默认值

  def initDrag(self):
    # 设置鼠标跟踪判断扳机默认值
    self._move_drag = False

  def initTitleLabel(self):
    # 安放标题栏标签
    self._TitleLabel = QTitleLabel(self)
    self._TitleLabel.setMouseTracking(True) # 设置标题栏标签鼠标跟踪(如不设,则标题栏内在widget上层,无法实现跟踪)
    self._TitleLabel.setIndent(150) # 设置标题栏文本缩进
    self._TitleLabel.move(0, 0) # 标题栏安放到左上角

  def initLayout(self):
    # 设置框架布局
    self._MainLayout = QVBoxLayout()
    self._MainLayout.setSpacing(0)
    self._MainLayout.addWidget(QLabel(), Qt.AlignLeft) # 顶一个QLabel在竖放框架第一行,以免正常内容挤占到标题范围里
    self._MainLayout.addStretch()
    self.setLayout(self._MainLayout)

  def addLayout(self, QLayout):
    # 给widget定义一个addLayout函数,以实现往竖放框架的正确内容区内嵌套Layout框架
    self._MainLayout.addLayout(QLayout)

  def _setTitleText(self, func):
    # 设置标题栏标签的装饰器函数
    def wrapper(*args):
      self._TitleLabel.setText(*args)
      return func(*args)
    return wrapper

  def setTitleAlignment(self, alignment):
    # 给widget定义一个setTitleAlignment函数,以实现标题栏标签的对齐方式设定
    self._TitleLabel.setAlignment(alignment | Qt.AlignVCenter)

  def setCloseButton(self, bool):
    # 给widget定义一个setCloseButton函数,为True时设置一个关闭按钮
    if bool == True:
      self._CloseButton = QTitleButton(b'\xef\x81\xb2'.decode("utf-8"), self)
      self._CloseButton.setObjectName("CloseButton") # 设置按钮的ObjectName以在qss样式表内定义不同的按钮样式
      self._CloseButton.setToolTip("关闭窗口")
      self._CloseButton.setMouseTracking(True) # 设置按钮鼠标跟踪(如不设,则按钮在widget上层,无法实现跟踪)
      self._CloseButton.setFixedHeight(self._TitleLabel.height()) # 设置按钮高度为标题栏高度
      self._CloseButton.clicked.connect(self.close) # 按钮信号连接到关闭窗口的槽函数

  def setMinMaxButtons(self, bool):
      # 给widget定义一个setMinMaxButtons函数,为True时设置最小化按钮
      if bool == True:
          self._MinimumButton = QTitleButton(b'\xef\x80\xb0'.decode("utf-8"), self)
          self._MinimumButton.setObjectName("MinMaxButton") # 设置按钮的ObjectName以在qss样式表内定义不同的按钮样式
          self._MinimumButton.setToolTip("最小化")
          self._MinimumButton.setMouseTracking(True) # 设置按钮鼠标跟踪(如不设,则按钮在widget上层,无法实现跟踪)
          self._MinimumButton.setFixedHeight(self._TitleLabel.height()) # 设置按钮高度为标题栏高度
          self._MinimumButton.clicked.connect(self.showMinimized) # 按钮信号连接到最小化窗口的槽函数

  def resizeEvent(self, QResizeEvent):
      # 自定义窗口调整大小事件
      self._TitleLabel.setFixedWidth(self.width()) # 将标题标签始终设为窗口宽度
      # 分别移动按钮到正确的位置
      try:
          self._CloseButton.move(self.width() - self._CloseButton.width(), 0)
      except:
          pass
      try:
          self._MinimumButton.move(self.width() - (self._CloseButton.width() + 1) * 2 + 1, 0)
      except:
          pass
  
  def mousePressEvent(self, event):
      # 重写鼠标点击的事件
      # 鼠标左键点击标题栏区域
      self._move_drag = True
      self.move_DragPosition = event.globalPos() - self.pos()
      event.accept()

  def mouseMoveEvent(self, QMouseEvent):
    # 鼠标手势
    self.setCursor(Qt.ArrowCursor)

    if Qt.LeftButton and self._move_drag:
      # 标题栏拖放窗口位置
      self.move(QMouseEvent.globalPos() - self.move_DragPosition)
      QMouseEvent.accept()

  def mouseReleaseEvent(self, QMouseEvent):
    # 鼠标释放后,各扳机复位
    self._move_drag = False

if __name__ == "__main__":
  from PyQt5.QtWidgets import QApplication
  import sys
  app = QApplication(sys.argv)
  app.setStyleSheet(open("./UnFrameStyle.qss").read())
  window = QUnFrameWindow()
  window.setCloseButton(True)
  window.setMinMaxButtons(True)
  window.show()
  sys.exit(app.exec_())

UnFrameStyle.qss文件中的代码:

/**********Title**********/
QTitleLabel{
    background-color: Gainsboro;
    font: 100 10pt;
}


/**********Button**********/
QTitleButton{
    background-color: rgba(255, 255, 255, 0);
    color: black;
    border: 0px;
    font: 100 10pt;
}
QTitleButton#MinMaxButton:hover{
    background-color: #D0D0D1;
    border: 0px;
    font: 100 10pt;
}
QTitleButton#CloseButton:hover{
    background-color: #D32424;
    color: white;
    border: 0px;
    font: 100 10pt;
}

有用点赞收藏加关注~

  • 19
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你可以使用PyQt库来实现一个带有输入框和提交按钮窗口。下面是一个简单的示例代码: ```python import sys from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QLineEdit, QPushButton class MyWindow(QWidget): def __init__(self): super().__init__() # 创建布局管理器 layout = QVBoxLayout() # 创建输入框 self.input_box = QLineEdit() layout.addWidget(self.input_box) # 创建提交按钮 self.submit_button = QPushButton("提交") self.submit_button.clicked.connect(self.submit) layout.addWidget(self.submit_button) # 将布局管理器应用到窗口 self.setLayout(layout) def submit(self): # 获取输入框的内容 input_text = self.input_box.text() print("提交内容:", input_text) if __name__ == "__main__": app = QApplication(sys.argv) window = MyWindow() window.show() sys.exit(app.exec_()) ``` 这段代码创建了一个继承自QWidget的自定义窗口类MyWindow。在构造函数中,我们创建了一个垂直布局管理器(QVBoxLayout)并将其应用到窗口上。然后,我们创建了一个QLineEdit对象作为输入框,并将其添加到布局中。接着,我们创建了一个QPushButton对象作为提交按钮,并将其添加到布局中。最后,我们定义了一个submit方法,在该方法中获取输入框的内容,并进行处理。 在if __name__ == "__main__"部分,我们创建了一个QApplication对象和MyWindow对象,并显示窗口。最后,通过调用app.exec_()来启动应用程序的事件循环。 你可以根据需要进行修改和扩展。希望这可以帮助到你!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值