我解决了我的第一个问题。每次我创建 QFontComboBox 时,都会列出“Monospace”,但选择它会给我另一种字体。很好 - 我已经删除了 QFontDatabase 中不存在的所有字体。这会删除“等宽”条目。
但是当我使用带有 courier 字体的 setCurrentFont 时,它会将该选项添加回下拉列表中。
这是在带有 QT 5.15 的 Linux 上(我刚刚尝试过 6.6.1,效果相同)。
我尝试进行自己的字体匹配,以便设置一种它当然应该知道的字体,但这没有帮助。这是我最新的测试代码 -
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
setupUi(this);
QFontDatabase db;
QStringList fontFamilies = db.families();
QStringList filteredFonts;
QFont defaultFont("Courier");
bool foundDefault = false;
for (const QString& family : fontFamilies)
{
if (family.startsWith("Courier"))
{
defaultFont = QFont(family);
foundDefault = true;
}
if (QFont(family).exactMatch())
{
filteredFonts.append(family);
}
}
fontComboBox->clear();
fontComboBox->addItems(filteredFonts);
if (foundDefault)
{
fontComboBox->setCurrentFont(defaultFont);
}
connect(fontComboBox, &QFontComboBox::currentFontChanged, this, &MainWindow::fontUpdate);
}
void MainWindow::fontUpdate(const QFont& font)
{
}
在我的系统上,它找到“Courier 10 Pitch”并将其用作默认值。我可以采取什么措施来阻止该虚假条目的弹出?
用户的问题是他们选择“Monospace”,但当他们再次返回时最终得到“DejaVu Sans Mono”。
谢谢
彼得
PS。这显示了基于已接受的解决方案的答案。我把原始代码留在那里注释掉了,但我不需要那部分。
void MainWindow::setCurrentFont(const QFont &font)
{
QFontInfo fi(font);
auto index = fontComboBox->findText(fi.family());
if (index >= 0) // && fi.family().contains(" ["))
{
fontComboBox->setCurrentIndex(index);
// strip *foundry* names
/*
auto family = fi.family().left(fi.family().indexOf(" ["));
index = fontComboBox->findText(family, Qt::MatchStartsWith);
if (index >= 0)
fontComboBox->setCurrentIndex(index);
*/
}
}
每当调用
setCurrentFont()
时,QFontComboBox always 都会更新其内部姓氏列表。
解决方案是永远不要直接调用该函数,而使用 QComboBox 的基本
setCurrentIndex()
,它内部连接到一个检查当前字体并最终更新它的函数。
不幸的是我不能用C++编写,但是下面基于你的原始代码的Python示例应该足够清晰了。
class MainWindow(QWidget):
def __init__(self):
super().__init__()
self.fontComboBox = QFontComboBox()
self.preview = QLabel('Hello world!')
layout = QVBoxLayout(self)
layout.addWidget(self.fontComboBox)
layout.addWidget(self.preview)
fontFamilies = QFontDatabase().families()
filteredFonts = []
defaultFont = QFont('Courier')
if QFontInfo(defaultFont).family() == defaultFont.family():
defaultFamily = defaultFont.family()
else:
defaultFamily = ''
for family in fontFamilies:
font = QFont(family)
if QFontInfo(font).family() == family:
if family.startswith('Courier') and not defaultFamily:
defaultFamily = family
filteredFonts.append(family)
self.fontComboBox.model().setStringList(filteredFonts)
self.fontComboBox.currentFontChanged.connect(self.preview.setFont)
if defaultFamily:
defaultIndex = self.fontComboBox.findText(defaultFamily)
if defaultIndex >= 0:
self.fontComboBox.setCurrentIndex(defaultIndex)
最后一个块还显示了
setCurrentFont()
的可能替代方案,以防您需要类似的功能,可以通过以下方式实现:
def setCurrentFont(self, font):
fi = QFontInfo(font)
index = self.fontComboBox.findText(fi.family())
if index < 0 and ' [' in fi.family():
# strip *foundry* names
family = fi.family()[:fi.family().index(' [')]
index = self.fontComboBox.findText(family, Qt.MatchStartsWith)
if index >= 0:
self.fontComboBox.setCurrentIndex(index)