帮助文档中有四个Rich Text的例子:Calendar, Order Form, Syntax High Lighter, Text Object。本博客展示前两个。
这个例子很简单,MainWindow类里添加一个QTextBrowser私有对象,并将此对象默认关联的QTextCursor对象进行编辑。添加Table和Frame。
本例中使用到了QDate类,它是Qt专门用于处理日期的类,currentDate()获取系统的日期;setDate(),fromString()可以设置日期;year(),month(),day()返回日期的年,月,日;年月日的这信息可以有各种格式:
Expression |
Output |
d |
the day as number without a leading zero (1 to 31) |
dd |
the day as number with a leading zero (01 to 31) |
ddd |
the abbreviated localized day name (e.g. 'Mon' to 'Sun'). Uses QDate::shortDayName(). |
dddd |
the long localized day name (e.g. 'Monday' to 'Sunday'). Uses QDate::longDayName(). |
M |
the month as number without a leading zero (1 to 12) |
MM |
the month as number with a leading zero (01 to 12) |
MMM |
the abbreviated localized month name (e.g. 'Jan' to 'Dec'). Uses QDate::shortMonthName(). |
MMMM |
the long localized month name (e.g. 'January' to 'December'). Uses QDate::longMonthName(). |
yy |
the year as two digit number (00 to 99) |
yyyy |
the year as four digit number. If the year is negative, a minus sign is prepended in addition. |
(注意,Qt会默认使用系统的语言,例如中文的shortDayName()是周一,周二等,longDayName()是星期一,星期二等。)
增加日期的方法:addMonths(); addYears(); addDays();daysTo()可以比较两个日期相差天数。对于闰年:isLeapYear()返回是否闰年。
下面展示的是本例子的核心代码(关于Rich Text的):
void MainWindow::insertCalendar() { editor->clear(); // 清空QTextBrowser上的内容 QTextCursor cursor = editor->textCursor(); // 获取cursor cursor.beginEditBlock(); // 开始块编辑 QDate date(selectedDate.year(), selectedDate.month(), 1); // 创建本月的第一天的日期对象,用于绘制 //! [5] //! [6] QTextTableFormat tableFormat; // 设置文本格式 tableFormat.setAlignment(Qt::AlignHCenter); tableFormat.setBackground(QColor("#e0e0e0")); tableFormat.setCellPadding(2); tableFormat.setCellSpacing(4); //! [6] //! [7] QVector<QTextLength> constraints; // 设置列宽 constraints << QTextLength(QTextLength::PercentageLength, 14) << QTextLength(QTextLength::PercentageLength, 14) << QTextLength(QTextLength::PercentageLength, 14) << QTextLength(QTextLength::PercentageLength, 14) << QTextLength(QTextLength::PercentageLength, 14) << QTextLength(QTextLength::PercentageLength, 14) << QTextLength(QTextLength::PercentageLength, 14); tableFormat.setColumnWidthConstraints(constraints); //! [7] //! [8] QTextTable *table = cursor.insertTable(1, 7, tableFormat); // 插入table //! [8] //! [9] QTextFrame *frame = cursor.currentFrame(); // root frame QTextFrameFormat frameFormat = frame->frameFormat(); frameFormat.setBorder(1); // 设置边缘宽1 frame->setFrameFormat(frameFormat); // 设置frame格式 //! [9] //! [10] QTextCharFormat format = cursor.charFormat(); // char格式 format.setFontPointSize(fontSize); // 设置字符大小 QTextCharFormat boldFormat = format; // 设置粗字体字体的格式 boldFormat.setFontWeight(QFont::Bold); QTextCharFormat highlightedFormat = boldFormat; // 设置高亮字的背景色的格式 highlightedFormat.setBackground(Qt::yellow); //! [10] //! [11] for (int weekDay = 1; weekDay <= 7; ++weekDay) { // 写上粗体的第一行:星期 QTextTableCell cell = table->cellAt(0, weekDay-1); //! [11] //! [12] QTextCursor cellCursor = cell.firstCursorPosition(); cellCursor.insertText(QString("%1").arg(QDate::shortDayName(weekDay)), boldFormat); } //! [12] //! [13] table->insertRows(table->rows(), 1); // 星期后插入一行 //! [13] while (date.month() == selectedDate.month()) { // 月份为当前月,绘制当前月日历 int weekDay = date.dayOfWeek(); QTextTableCell cell = table->cellAt(table->rows()-1, weekDay-1); QTextCursor cellCursor = cell.firstCursorPosition(); if (date == QDate::currentDate()) // 将系统当前的这天高亮 cellCursor.insertText(QString("%1").arg(date.day()), highlightedFormat); else cellCursor.insertText(QString("%1").arg(date.day()), format); date = date.addDays(1); // date的日期加一天 if (weekDay == 7 && date.month() == selectedDate.month()) table->insertRows(table->rows(), 1); // 到达一行的末端(星期天)转向下一行 } cursor.endEditBlock(); // 结束块编辑 //! [14] setWindowTitle(tr("Calendar for %1 %2" // 该边标题 ).arg(QDate::longMonthName(selectedDate.month()) ).arg(selectedDate.year())); }
本例是一个订货小模拟软件,主程序打开后生成一个默认的订单。菜单中选择File->New可以订购新订单:将弹出如图中的Details对话框。填写信息后点击OK,程序将为之创建一个订单标签展示于当前TabWidget中。这里只展示出在住程序中是如何编辑rich text的代码。
void MainWindow::createLetter(const QString &name, const QString &address, QList<QPair<QString,int> > orderItems, bool sendOffers) { QTextEdit *editor = new QTextEdit; // 创建QTextEdit到标签页标签 int tabIndex = letters->addTab(editor, name); letters->setCurrentIndex(tabIndex); // 设置标签当前索引 //! [1] //! [2] QTextCursor cursor(editor->textCursor()); // 获取QTextEdit对象的cursor cursor.movePosition(QTextCursor::Start); // 移到开始位置 //! [2] //! [3] QTextFrame *topFrame = cursor.currentFrame(); // root frame QTextFrameFormat topFrameFormat = topFrame->frameFormat(); topFrameFormat.setPadding(16); topFrame->setFrameFormat(topFrameFormat); // root frame设置frame格式 QTextCharFormat textFormat; QTextCharFormat boldFormat; boldFormat.setFontWeight(QFont::Bold); QTextFrameFormat referenceFrameFormat; // 用于右上方显示信息的框格式 referenceFrameFormat.setBorder(1); referenceFrameFormat.setPadding(8); referenceFrameFormat.setPosition(QTextFrameFormat::FloatRight); referenceFrameFormat.setWidth(QTextLength(QTextLength::PercentageLength, 40)); cursor.insertFrame(referenceFrameFormat); // 添加refernceFrameFormat格式的框到root frame cursor.insertText("A company", boldFormat); cursor.insertBlock(); cursor.insertText("321 City Street"); cursor.insertBlock(); cursor.insertText("Industry Park"); cursor.insertBlock(); cursor.insertText("Another country"); //! [3] //! [4] cursor.setPosition(topFrame->lastPosition()); // 光标移出到上一位置,这里是指开始位置 cursor.insertText(name, textFormat); // 插入文本,订货者信息 QString line; foreach (line, address.split("\n")) { // 将address信息分解换行展示 cursor.insertBlock(); cursor.insertText(line); } //! [4] //! [5] cursor.insertBlock(); // 插入新块,分隔作用 cursor.insertBlock(); QDate date = QDate::currentDate(); // 当前系统时间,即生成订单的时间 cursor.insertText(tr("Date: %1").arg(date.toString("d MMMM yyyy")), textFormat); // 插入文本:订单生成时间 cursor.insertBlock(); // 换行 QTextFrameFormat bodyFrameFormat; // 定义一个文本框bodyFrameFormat,没有边框 bodyFrameFormat.setWidth(QTextLength(QTextLength::PercentageLength, 100)); cursor.insertFrame(bodyFrameFormat); // 插入框到root frame //! [5] //! [6] // 插入文本 cursor.insertText(tr("I would like to place an order for the following " "items:"), textFormat); cursor.insertBlock(); //! [6] //! [7] cursor.insertBlock(); // 间隔行 //! [7] //! [8] QTextTableFormat orderTableFormat; // 订单表 orderTableFormat.setAlignment(Qt::AlignHCenter); // 横向中央对齐 QTextTable *orderTable = cursor.insertTable(1, 2, orderTableFormat); // 插入一行两列的表 QTextFrameFormat orderFrameFormat = cursor.currentFrame()->frameFormat(); // 包含订单表的框格式 orderFrameFormat.setBorder(1); // 设置1个单位边缘 cursor.currentFrame()->setFrameFormat(orderFrameFormat); // 插入框到 bodyFrame //! [8] //! [9] cursor = orderTable->cellAt(0, 0).firstCursorPosition(); // 添加表元素 cursor.insertText(tr("Product"), boldFormat); cursor = orderTable->cellAt(0, 1).firstCursorPosition(); cursor.insertText(tr("Quantity"), boldFormat); //! [9] //! [10] for (int i = 0; i < orderItems.count(); ++i) { // 添加order表中的数据 QPair<QString,int> item = orderItems[i]; int row = orderTable->rows(); orderTable->insertRows(row, 1); cursor = orderTable->cellAt(row, 0).firstCursorPosition(); cursor.insertText(item.first, textFormat); cursor = orderTable->cellAt(row, 1).firstCursorPosition(); cursor.insertText(QString("%1").arg(item.second), textFormat); } //! [10] //! [11] cursor.setPosition(topFrame->lastPosition()); cursor.insertBlock(); //! [11] //! [12] cursor.insertText(tr("Please update my records to take account of the " "following privacy information:")); cursor.insertBlock(); //! [12] //! [13] QTextTable *offersTable = cursor.insertTable(2, 2); // 插入一个2*2的表 cursor = offersTable->cellAt(0, 1).firstCursorPosition(); // 为第二列位置插入文本 cursor.insertText(tr("I want to receive more information about your " "company's products and special offers."), textFormat); cursor = offersTable->cellAt(1, 1).firstCursorPosition(); cursor.insertText(tr("I do not want to receive any promotional information " "from your company."), textFormat); if (sendOffers) // 根据是否选中了sendOffers选择光标放置位置 cursor = offersTable->cellAt(0, 0).firstCursorPosition(); else cursor = offersTable->cellAt(1, 0).firstCursorPosition(); cursor.insertText("X", boldFormat); // 插入文本"X" //! [13] //! [14] cursor.setPosition(topFrame->lastPosition()); // 在最后插入文本 cursor.insertBlock(); cursor.insertText(tr("Sincerely,"), textFormat); cursor.insertBlock(); cursor.insertBlock(); cursor.insertBlock(); cursor.insertText(name); printAction->setEnabled(true); // 设置打印动作可用了 }