精通Qt4编程
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

6.3 用不同的字体

Qt提供了QFont类来表示字体。当创建QFont对象时,Qt会使用指定的字体,如果没有对应的字体,Qt将寻找一种最接近的已安装字体。字体信息可以通过QFontInfo取出,并可用QFontMetrics取得字体的相关数据。函数exactMatch()判断底层窗口系统中是否有完全对应的字体。

使用QApplication::setFont()可以设置应用程序的默认字体。如果选择的字体不包括所有要显示的字符,QFont将会尝试寻找最接近的字体。当QPainter绘制指定字体中不存在的字符时,将绘制一个空心的正方形。

下面编写一个小程序将系统的所有字体显示出来。程序的主窗口定义如下:

        #ifndef MAINWINDOW_H
        #define MAINWINDOW_H

        #include <QtGui>
        class MainWindow : public QMainWindow
        {
            Q_OBJECT

        public:
            MainWindow(QWidget *parent = 0);

        protected slots:
            void changeFontColor();
            void fontSizeChanged(const QString &text);

        private:
            void createActions();
            void createMenus();
            void createToolBars();
            void listAllFonts();
            void updateColor();

            QScrollArea *scrollArea;
            QTextEdit *fontEdit;

            QMenu *fontMenu;
            QToolBar *fontToolBar;
            QComboBox *sizeComboBox;
            QAction *fontColorAct;

            uint fontSize;
            bool bShowStyles;
            QColor fontColor;
        };
        #endif

将字体全部显示的函数如下所示:

        void MainWindow::listAllFonts()
        {
            QFont font;
            QTextCharFormat textFormat;
            QFontDatabase database;
            QTextCursor cursor;

            textFormat.setForeground(fontColor);
            fontEdit->clear();
              foreach (QString family, database.families()) {
                const QStringList styles = database.styles(family);
                foreach(QString style, styles) {
                    font = QFont(family, fontSize, database.weight(family, style),
                database.italic(family, style));
                    textFormat.setFont(font);
                    cursor = fontEdit->textCursor();
              cursor.insertText(QString("%1 %2").arg(family).arg(style),
                textFormat);
                    cursor.insertBlock();
                }
            }
        }

这个函数中使用了QFontDatabase类取得所有的系统字体,再用foreach循环查询每种字体的风格。字体的风格使用QFontDatabase类的styles()函数查询,可能的风格有“Bold”,“Light Italic”,“Oblique”等。这样得到所有的字体及其风格,建立相应的字符在QTextEdit控件中显示。

另外还设置了改变显示字体的大小和颜色的菜单。相应的槽函数如下:

        void MainWindow::changeFontColor()
        {
            QColor color = QColorDialog::getColor(fontColor, this);
            if (color.isValid()) {
                fontColor = color;
                updateColor();
                listAllFonts();
            }
        }

        void MainWindow::fontSizeChanged(const QString &text)
        {
            fontSize = text.toUInt();
            if(fontSize > 0)
                listAllFonts();
        }

设置字体大小的方法有两种,分别是setPointSize()和setPixelSize()。其中setPixelSize()是设备相关的,setPointSize()是设备无关的。

最后给出主窗口初始化的代码。

        MainWindow::MainWindow(QWidget *parent)
          : QMainWindow(parent)
        {
            fontColor = Qt::black;
            fontSize = 16;

            createActions();
            createToolBars();
            createMenus();
            updateColor();

            fontEdit = new QTextEdit();
            setCentralWidget(fontEdit);

            resize(800,600);
            listAllFonts();
        }

        void MainWindow::createActions()
        {
            fontColorAct = new QAction(QPixmap(32, 32), tr("Change Color..."), this);
            connect(fontColorAct, SIGNAL(triggered()), this,
                SLOT(changeFontColor()));
        }

        void MainWindow::createMenus()
        {
            fontMenu = menuBar()->addMenu(tr("&Font"));
            fontMenu->addAction(fontColorAct);
        }

        void MainWindow::createToolBars()
        {
            fontToolBar = addToolBar(tr("FontColor"));
            fontToolBar->addAction(fontColorAct);
            fontToolBar->addSeparator();
            QStringList fontSizes;
            fontSizes << "32" << "24" << "16" << "14" << "12" << "8" << "4" << "2";
            sizeComboBox = new QComboBox();
            sizeComboBox->setMinimumWidth(100);
            sizeComboBox->setEditable(true);
            sizeComboBox->addItems(fontSizes);
            sizeComboBox->setValidator(new QIntValidator(1, 65535, this));
            sizeComboBox->setCurrentIndex(2);
            fontToolBar->addWidget(sizeComboBox);
            connect(sizeComboBox, SIGNAL(editTextChanged(const QString&)), this,
              SLOT(fontSizeChanged(const QString&)));
        }

        void MainWindow::updateColor()
        {
            QPixmap pixmap(32, 32);
            QPainter painter(&pixmap);
            painter.fillRect(0, 0, 32, 32, fontColor);

            QColor lighter = fontColor.light();
            painter.setPen(lighter);
            QPoint lightFrame[] = { QPoint(0, 31), QPoint(0, 0), QPoint(31, 0) };
            painter.drawPolyline(lightFrame, 3);

            painter.setPen(fontColor.dark());
            QPoint darkFrame[] = { QPoint(1, 31), QPoint(31, 31), QPoint(31, 1) };
            painter.drawPolyline(darkFrame, 3);
            painter.end();

            fontColorAct->setIcon(pixmap);
        }

updateColor()是生成当前颜色工具按钮的函数,程序运行效果如图6-12所示。

图6-12 系统字体显示