【问题标题】:How to set non-selectable default text on QComboBox?如何在 QComboBox 上设置不可选择的默认文本?
【发布时间】:2011-11-29 18:21:37
【问题描述】:

使用填充了项目的常规QComboBox,如果currentIndex 设置为-1,则小部件为空。在下拉列表中未显示的组合框中显示初始描述性文本(例如“--Select Country--”、“--Choose Topic--”等)将非常有用。

我在文档中找不到任何内容,也找不到任何以前的问题的答案。

【问题讨论】:

    标签: c++ qt qcombobox


    【解决方案1】:

    在组合框 API 中似乎没有预料到这种情况。但是,凭借底层模型的灵活性,您似乎应该能够将您的 --Select Country-- 添加为第一个“合法”项目,然后使其不被用户选择:

    QStandardItemModel* model =
            qobject_cast<QStandardItemModel*>(comboBox->model());
    QModelIndex firstIndex = model->index(0, comboBox->modelColumn(),
            comboBox->rootModelIndex());
    QStandardItem* firstItem = model->itemFromIndex(firstIndex);
    firstItem->setSelectable(false);
    

    根据您想要的精确行为,您可能希望改用setEnabled。或者我个人更喜欢它,如果它只是我可以将其设置回的不同颜色的项目:

    Qt, How do I change the text color of one item of a QComboBox? (C++)

    (我不喜欢当我点击某个东西然后被困在我无法回到原来的地方时,即使它是一个尚未选择的状态!)

    【讨论】:

    • 太棒了!显然Qt的一部分我没有接触过,这对于定制来说似乎非常有用。从您链接到的 SO 问题中,更改背景颜色使其看起来非常漂亮,并且可能比我最初设想的要好。 firstItem->setData(Qt::lightGray , Qt::BackgroundRole); (如果您将此添加到您的答案中,我不介意)。
    • @EXIT_FAILURE 我认为您的评论涵盖了您的替代方案,因为我没有尝试过,所以我不知道我是否喜欢它。 :) 但是,是的,Qt 提供了一些独创性,如果我们都联合起来,也许我们可以停止 GTK 和 wxWidgets! :-/ stackoverflow.com/questions/7545804/…
    • 从 Qt 5.15 开始,正确的做法是 setPlaceholderText 在这里回答 stackoverflow.com/a/63937462/20984
    【解决方案2】:

    您可以执行类似操作的一种方法是设置占位符:

    comboBox->setPlaceholderText(QStringLiteral("--Select Country--"));
    comboBox->setCurrentIndex(-1);
    

    这样你就有了一个无法选择的默认值。

    【讨论】:

      【解决方案3】:

      从 PyQt5 将我的解决方案留在这里。创建一个代理模型并将所有行下移一位,并在第 0 行返回一个默认值。

      class NullRowProxyModel(QAbstractProxyModel):
          """Creates an empty row at the top for null selections on combo boxes
          """
      
          def __init__(self, src, text='---', parent=None):
              super(NullRowProxyModel, self).__init__(parent)
              self._text = text
              self.setSourceModel(src)
      
          def mapToSource(self, proxyIndex: QModelIndex) -> QModelIndex:
              if self.sourceModel():
                  return self.sourceModel().index(proxyIndex.row()-1, proxyIndex.column())
              else:
                  return QModelIndex()
      
          def mapFromSource(self, sourceIndex: QModelIndex) -> QModelIndex:
              return self.index(sourceIndex.row()+1, sourceIndex.column())
      
          def data(self, proxyIndex: QModelIndex, role=Qt.DisplayRole) -> typing.Any:
              if proxyIndex.row() == 0 and role == Qt.DisplayRole:
                  return self._text
              elif proxyIndex.row() == 0 and role == Qt.EditRole:
                  return None
              else:
                  return super(NullRowProxyModel, self).data(proxyIndex, role)
      
          def index(self, row: int, column: int, parent: QModelIndex = ...) -> QModelIndex:
              return self.createIndex(row, column)
      
          def parent(self, child: QModelIndex) -> QModelIndex:
              return QModelIndex()
      
          def rowCount(self, parent: QModelIndex = ...) -> int:
              return self.sourceModel().rowCount()+1 if self.sourceModel() else 0
      
          def columnCount(self, parent: QModelIndex = ...) -> int:
              return self.sourceModel().columnCount() if self.sourceModel() else 0
      
          def headerData(self, section: int, orientation: Qt.Orientation, role: int = ...) -> typing.Any:
              if not self.sourceModel():
                  return None
              if orientation == Qt.Vertical:
                  return self.sourceModel().headerData(section-1, orientation, role)
              else:
                  return self.sourceModel().headerData(section, orientation, role)

      【讨论】:

      • 谢谢。在树莓派(5.11.3)上的旧版 Qt 上运行良好。使用工作示例 here 创建了更详细的答案
      猜你喜欢
      • 2012-11-26
      • 2014-04-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-18
      • 1970-01-01
      • 1970-01-01
      • 2019-06-21
      相关资源
      最近更新 更多