1. 程式人生 > 程式設計 >自定義實現 PyQt5 下拉複選框 ComboCheckBox的完整程式碼

自定義實現 PyQt5 下拉複選框 ComboCheckBox的完整程式碼

自定義實現 PyQt5 下拉複選框 ComboCheckBox

一、前言

由於最近的專案需要具有複選功能,但過多的複選框會影響介面佈局和美觀,因而想到把 PyQt5 的下拉列表和複選框結合起來,但在 PyQt5 中並沒有這樣的元件供我們使用,所以想要自己實現一個下拉複選框,主要就是繼承 QComboBox 類,然後將複選框 QCheckBox 加入其中,並實現相應的功能。

最終實現的下拉複選框效果如下:

自定義實現 PyQt5 下拉複選框 ComboCheckBox的完整程式碼

二、程式碼實現

1.主要方法

在 PyQt5 中,有幾個主要的方法需要了解一下,方法名稱和對應的含義如下:

QtWidgets.QComboBox.setView( itemView ) :設定 組合框彈出視窗中使用的檢視 , 組合框獲取檢視的所有權。

QtWidgets.QcomboBox.setLineEdit( QLineEdit ) : 設定組合框 使用 的行 ,而不是當前行編輯視窗小部件。
QtWidgets.QListWidget.setItemWidget(item,widget) : 設定 要在給定的 item 中的 widget 元件 。

2.具體程式碼

實現下拉複選框的思路為用 setView() 方法將 QComboBox 下拉列表的檢視改為 QListWidget 元件,然後將 QCheckBox 複選框用在 QListWiget 中,具體程式碼如下:

class ComboCheckBox(QComboBox):
  def __init__(self,items: list):
    """
    initial function
    :param items: the items of the list
    """
    super(ComboCheckBox,self).__init__()
    self.items = items # items list
    self.box_list = [] # selected items
    self.text = QLineEdit() # use to selected items
    self.text.setReadOnly(True)
    q = QListWidget()
    for i in range(len(self.items)):
      self.box_list.append(QCheckBox())
      self.box_list[i].setText(self.items[i])
      item = QListWidgetItem(q)
      q.setItemWidget(item,self.box_list[i])
      self.box_list[i].stateChanged.connect(self.show_selected)
    self.setLineEdit(self.text)
    self.setModel(q.model())
    self.setView(q)
  def get_selected(self) -> list:
    """
    get selected items
    :return:
    """
    ret = []
    for i in range(len(self.items)):
      if self.box_list[i].isChecked():
        ret.append(self.box_list[i].text())
    return ret
  def show_selected(self):
    """
    show selected items
    :return:
    """
    self.text.clear()
    ret = '; '.join(self.get_selected())
    self.text.setText(ret)

其中 show_selected() 用於顯示被選中的內容,get_selected() 則用於獲取所有被選中的內容並返回。

3.增加全選

要增加全選功能,首先是要在最前面加一個全選的選擇框,然後為這個全選的選擇框繫結相應的方法,用於實現全選功能和取消全選功能,具體程式碼如下:

def all_selected(self):
  """
  decide whether to check all
  :return:
  """
  # change state
  if self.state == 0:
    self.state = 1
    for i in range(1,len(self.items)):
      self.box_list[i].setChecked(True)
  else:
    self.state = 0
    for i in range(1,len(self.items)):
      self.box_list[i].setChecked(False)
  self.show_selected()

4.修改樣式

由於預設的樣式並不美觀,所以我們可以對控制元件的樣式進行自定義,例如字型大小、字型粗細等等,例如:

q.setStyleSheet("font-size: 20px; font-weight: bold; height: 40px; margin-left: 5px") self.setStyleSheet("width: 300px; height: 50px; font-size: 21px; font-weight: bold")

三、完整程式

完善後的下拉複選框的執行程式程式碼如下:

from PyQt5.QtWidgets import QComboBox,QLineEdit,QListWidgetItem,QListWidget,QCheckBox,\
  QApplication,QVBoxLayout,QWidget
import sys
class ComboCheckBox(QComboBox):
  def __init__(self,self).__init__()
    self.items = ["全選"] + items # items list
    self.box_list = [] # selected items
    self.text = QLineEdit() # use to selected items
    self.state = 0 # use to record state
    q = QListWidget()
    for i in range(len(self.items)):
      self.box_list.append(QCheckBox())
      self.box_list[i].setText(self.items[i])
      item = QListWidgetItem(q)
      q.setItemWidget(item,self.box_list[i])
      if i == 0:
        self.box_list[i].stateChanged.connect(self.all_selected)
      else:
        self.box_list[i].stateChanged.connect(self.show_selected)
    q.setStyleSheet("font-size: 20px; font-weight: bold; height: 40px; margin-left: 5px")
    self.setStyleSheet("width: 300px; height: 50px; font-size: 21px; font-weight: bold")
    self.text.setReadOnly(True)
    self.setLineEdit(self.text)
    self.setModel(q.model())
    self.setView(q)
  def all_selected(self):
    """
    decide whether to check all
    :return:
    """
    # change state
    if self.state == 0:
      self.state = 1
      for i in range(1,len(self.items)):
        self.box_list[i].setChecked(True)
    else:
      self.state = 0
      for i in range(1,len(self.items)):
        self.box_list[i].setChecked(False)
    self.show_selected()
  def get_selected(self) -> list:
    """
    get selected items
    :return:
    """
    ret = []
    for i in range(1,len(self.items)):
      if self.box_list[i].isChecked():
        ret.append(self.box_list[i].text())
    return ret
  def show_selected(self):
    """
    show selected items
    :return:
    """
    self.text.clear()
    ret = '; '.join(self.get_selected())
    self.text.setText(ret)
class UiMainWindow(QWidget):
  def __init__(self):
    super(UiMainWindow,self).__init__()
    self.setWindowTitle('Test')
    self.resize(600,400)
    combo = ComboCheckBox(["Python","Java","Go","C++","JavaScript","PHP"])
    layout = QVBoxLayout()
    layout.addWidget(combo)
    self.setLayout(layout)
if __name__ == "__main__":
  app = QApplication(sys.argv)
  ui = UiMainWindow()
  ui.show()
  sys.exit(app.exec_())

總結

到此這篇關於自定義實現 PyQt5 下拉複選框 ComboCheckBox的完整程式碼的文章就介紹到這了,更多相關PyQt5 下拉複選框 ComboCheckBox內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!