帮助文档中有四个Rich Text的例子:Calendar, Order Form, Syntax High Lighter, Text Object。本博客展示前两个。
Calendar
这个例子很简单,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()));
}
Order Form
本例是一个订货小模拟软件,主程序打开后生成一个默认的订单。菜单中选择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); // 设置打印动作可用了
}