应用程序中经常需要设置字体,例如office软件或者是其他的编辑器软件等等。这里主要涉及到如下几个概念:字体,字号以及风格(例如:粗体,斜体,下划线等等)。Qt里面也有对应的类。接下来我们主要对这几个类进行详细的说明,最后举例说明它们的应用。
QFontDatabase类提供了底层窗口系统所提供的系统可用的字体。
该类最常见的用法就是调用接口查询数据库,获取系统支持的字体,以及每种字体支持的大小和风格。smoothSizes()类似pointSizes(),但是前者返回的是在某种字体(family)下某种风格(style)支持的最好的字号。
font()函数返回指定的字体,风格和字号的QFont。
QFontDatabase也支持一些静态函数,例如:standardSizes()。可以使用writingSystemName()获取对应writingSystem的字符串描述。
代码片段:
QFontDatabase database; QTreeWidget fontTree; fontTree.setColumnCount(2); fontTree.setHeaderLabels(QStringList() << "Font" << "Smooth Sizes"); foreach (const QString &family, database.families()) { QTreeWidgetItem *familyItem = new QTreeWidgetItem(&fontTree); familyItem->setText(0, family); foreach (const QString &style, database.styles(family)) { QTreeWidgetItem *styleItem = new QTreeWidgetItem(familyItem); styleItem->setText(0, style); QString sizes; foreach (int points, database.smoothSizes(family, style)) sizes += QString::number(points) + " "; styleItem->setText(1, sizes.trimmed()); } }
QFont类用于创建绘制文本的字体。当创建QFont对象的时候,可以指定一系列的属性。Qt将会使用指定的属性,但是如果没有这些属性,Qt就会选择与指定的最相近的属性来代替。我们可以使用QFontInfo对象获取实际使用的font属性。
如果窗口系统提供准确的exactMatch,也就是exactMatch()函数返回true,那么就可以使用QFontMetrics类获取实际数据,例如:QFontMetrics::width()函数返回字符的像素的宽度。
在使用QFont之前必须先指定QGuiApplication的实例,我们可以使用QGuiApplication::setFont()设置应用的默认font。
如果选择了一个字体,但是该字体不包括所有需要显示的字符,QFont就会寻找最近的font的字符。
我们可以像下面这样创建font:
QFont serifFont("Times", 10, QFont::Bold);
QFont sansFont("Helvetica [Cronyx]", 12);
在构造函数中指定的属性也可以稍后通过成员函数设置。QFontInfo必须在font所有属性都设置之后再创建。QFontInfo用于获取QFont的信息,但是QFontInfo不会更新,哪怕对应的QFont使用的属性发生了改变,QFontInfo也不会得到更新,通过QFontInfo获取的信息依然是最初设置的。
如果请求的QFont不可用,你可以调用setStyleHint()来改变font matching algorithm,可以通过调用defaultFamily()获取默认的family。
每一个QFont都有一个key可以使用,类似字典中的key一样,如果你想存储用户的font偏好设置,那么你可以使用QSettings,可以使用toString()写入,使用fromString()读出,操作符“《《”和“》》”依旧可以使用,但是这两个操作符用于数据流。
我们可以通过setPixelSize()设置字符显示的高度,但是setPointSize()可以达到类似的效果而且是设备无关的。
在X11系统下,我们可以使用setRawName()来设置font。加载font将会会是十分昂贵的,特别在X11上。
font matching algorithm工作流程如下:
*)搜索指定的font family;
*)如果上一步没有找到,就使用styleHint()选择一个替代的字体;
*)搜索上面找到的替代的字体;
*)上面的搜索都没有找到或者是没有styleHint(),那么就使用“helvetica”进行搜索;
*)如果“helvetica”没有找到,那么Qt就会使用lastResortFamily();
*)如果lastResortFamily()没有搜索到,那么使用lastResortFont(),该调用总是会返回一个可用的。
当family匹配之后就会再匹配属性,属性的匹配顺序如下:
*)fixedPitch()
*)pointSize() (see below)
*)weight()
*)style()
优先匹配family,再匹配属性。
To find out font metrics use a QFontMetrics object, e.g.
QFontMetrics fm(f1); int textWidthInPixels = fm.width("How many pixels wide is this text?"); int textHeightInPixels = fm.height();
这两个类用于获取字体的像素信息,例如字体的高度,一个给定字符串的像素宽度等等。
#include "mainwindow.h" #include "ui_mainwindow.h" #include <QFontDatabase> #include <QDebug> struct tagWritingSystem { QString WritingSystemName; int enWritingSystemId; }; tagWritingSystem WritingSystemArry[] = { {"Latin", 1}, {"Greek", 2}, {"Cyrillic", 3}, {"Armenian", 4}, {"Hebrew", 5}, {"Arabic", 6}, {"Syriac", 7}, {"Thaana", 8}, {"Devanagari", 9}, {"Bengali", 10}, {"Gurmukhi", 11}, {"Gujarati", 12}, {"Oriya", 13}, {"Tamil", 14}, {"Telugu", 15}, }; MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); QFontDatabase db; /* First display all the Writing System */ for(int index = 0; index < db.writingSystems().length(); index++) { ; } for(int index = 0; index < 15; index++) { ui->comboBox->addItem(WritingSystemArry[index].WritingSystemName); } int currIndex = 0; for(int index = 0; index < 15; index++) { if (ui->comboBox->currentText() == WritingSystemArry[index].WritingSystemName) { currIndex = index; break; } } /* Filter the Family by Writing System */ ui->FamilyCb->addItems(db.families((QFontDatabase::WritingSystem)currIndex)); /* Filter the Style by Family */ ui->StyleCb->addItems(db.styles(ui->FamilyCb->currentText())); /* Insert the Size */ foreach (int var, db.standardSizes()) { ui->SizeCb->addItem(QString::number(var)); } /* Font:a specific size and style of type within a type family */ QFont font = db.font(ui->FamilyCb->currentText(), ui->StyleCb->currentText(), ui->SizeCb->currentText().toInt()); qDebug() << font.family() << ":" << font.styleName(); /* set the font */ //QGuiApplication::setFont(font); ui->FontLabel->setFont(font); ui->FontLabel->setText(font.family() + ":" + font.styleName()); QFontInfo fontinfo = this->fontInfo(); qDebug() << fontinfo.family() + ":" + fontinfo.styleName(); } MainWindow::~MainWindow() { delete ui; } void MainWindow::on_comboBox_currentTextChanged(const QString &arg1) { QFontDatabase db; qDebug() << arg1; qDebug() << ui->comboBox->currentText(); int currIndex = 0; for(int index = 0; index < 15; index++) { if (ui->comboBox->currentText() == WritingSystemArry[index].WritingSystemName) { currIndex = index; break; } } qDebug() << currIndex; ui->FamilyCb->addItems(db.families((QFontDatabase::WritingSystem)currIndex)); } void MainWindow::on_FamilyCb_currentTextChanged(const QString &arg1) { QFontDatabase db; qDebug() << arg1; ui->StyleCb->addItems(db.styles(ui->FamilyCb->currentText())); } void MainWindow::on_StyleCb_currentTextChanged(const QString &arg1) { QFontDatabase db; qDebug() << arg1; /* Font:a specific size and style of type within a type family */ QFont font = db.font(ui->FamilyCb->currentText(), ui->StyleCb->currentText(), ui->SizeCb->currentText().toInt()); qDebug() << font.family() << ":" << font.styleName(); /* set the font */ font.setBold(true); font.setUnderline(true); ui->FontLabel->setFont(font); ui->FontLabel->setText(font.family() + ":" + font.styleName()); } void MainWindow::on_SizeCb_currentTextChanged(const QString &arg1) { QFontDatabase db; qDebug() << arg1; /* Font:a specific size and style of type within a type family */ QFont font = db.font(ui->FamilyCb->currentText(), ui->StyleCb->currentText(), ui->SizeCb->currentText().toInt()); qDebug() << font.family() << ":" << font.styleName(); /* set the font */ font.setBold(true); font.setUnderline(true); ui->FontLabel->setFont(font); ui->FontLabel->setText(font.family() + ":" + font.styleName()); }