Qt Dock Widgets 官方示例的翻译
目錄名字
- Qt Dock Widgets 官方示例的翻譯
- Dock Widgets Example 介紹:
- MainWindow Class 定義:
- MainWindow Class 關聯的相關頭文件
- 相關函數功能的介紹:
- 總結:
Qt Dock Widgets 官方示例的翻譯
Dock Widgets Example 介紹:
Dock Widgets 示例程序描述的有兩個技術要點:
- 1、如何添加Dock 窗體到應用程序中。
- 2、如何使用Qt的富文本引擎。
該示例應用程序描述的是一個簡單的處理商業郵件的模板程序。在兩個Dock 窗體中分別顯示了客戶的信息 和 常用語。通過單擊Dock中的列表,將自定添加選中的信息添加到郵件模板中。當然,撤銷按鈕可以撤去郵件模板中錯誤的或者不需要的信息。一旦郵件完成,可以直接答應或者保存為HTML格式。
MainWindow Class 定義:
class MainWindow : public QMainWindow{Q_OBJECTpublic:MainWindow();private slots:void newLetter();void save();void print();void undo();void about();void insertCustomer(const QString &customer);void addParagraph(const QString ¶graph);private:void createActions();void createStatusBar();void createDockWindows();QTextEdit *textEdit;QListWidget *customerList;QListWidget *paragraphsList;QMenu *viewMenu;};接著,我們來一個個來了解每個函數的功能。
MainWindow Class 關聯的相關頭文件
#include
#if defined(QT_PRINTSUPPORT_LIB)
#include <QtPrintSupport/qtprintsupportglobal.h>
#if QT_CONFIG(printdialog)
#include
#endif
#endif
#include “mainwindow.h”
相關函數功能的介紹:
一開始我們包含了 ,QWidget類是所有用戶界面對象的基類。我們同樣需要包含mainwindow.h
MainWindow::MainWindow(): textEdit(new QTextEdit){setCentralWidget(textEdit);createActions();createStatusBar();createDockWindows();setWindowTitle(tr("Dock Widgets"));newLetter();setUnifiedTitleAndToolBarOnMac(true);}在該構造函數中,我們一開始就創建了QTextEdit Widget。 然后我們調用QMainWindow::setCentralWidget()。 該函數會將 QTextEdit 的所有權傳遞給 MainWindow ,同時QTextEdit 會占據MainWindow 的中央區域。
然后我們調用 createActions(), createMenus(), createToolBars(), createStatusBar(), and createDockWindows() 來初始化窗體.。
最后,我們調用 setWindowTitle() 來給用用程序設定一個名稱, newLetter() 來創建一個郵件模板。
我們 調用 createActions(), createMenus(), createToolBars(), and createStatusBar() 函數,是為了保持和其他的Qt示例程序的風格保持一致。
void MainWindow::createDockWindows(){QDockWidget *dock = new QDockWidget(tr("Customers"), this);dock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);customerList = new QListWidget(dock);customerList->addItems(QStringList()<< "John Doe, Harmony Enterprises, 12 Lakeside, Ambleton"<< "Jane Doe, Memorabilia, 23 Watersedge, Beaton"<< "Tammy Shea, Tiblanka, 38 Sea Views, Carlton"<< "Tim Sheen, Caraba Gifts, 48 Ocean Way, Deal"<< "Sol Harvey, Chicos Coffee, 53 New Springs, Eccleston"<< "Sally Hobart, Tiroli Tea, 67 Long River, Fedula");dock->setWidget(customerList);addDockWidget(Qt::RightDockWidgetArea, dock);viewMenu->addAction(dock->toggleViewAction());dock = new QDockWidget(tr("Paragraphs"), this);paragraphsList = new QListWidget(dock);paragraphsList->addItems(QStringList()<< "Thank you for your payment which we have received today."<< "Your order has been dispatched and should be with you ""within 28 days."<< "We have dispatched those items that were in stock. The ""rest of your order will be dispatched once all the ""remaining items have arrived at our warehouse. No ""additional shipping charges will be made."<< "You made a small overpayment (less than $5) which we ""will keep on account for you, or return at your request."<< "You made a small underpayment (less than $1), but we have ""sent your order anyway. We'll add this underpayment to ""your next bill."<< "Unfortunately you did not send enough money. Please remit ""an additional $. Your order will be dispatched as soon as ""the complete amount has been received."<< "You made an overpayment (more than $5). Do you wish to ""buy more items, or should we return the excess to you?");dock->setWidget(paragraphsList);addDockWidget(Qt::RightDockWidgetArea, dock);viewMenu->addAction(dock->toggleViewAction());connect(customerList, &QListWidget::currentTextChanged,this, &MainWindow::insertCustomer);connect(paragraphsList, &QListWidget::currentTextChanged,this, &MainWindow::addParagraph);}我們創建一個關于客戶信息的Dock 窗體,設定了該窗體的標題,我們同時傳遞“this”指針,這樣就指定了MainWindows為父窗體。一般情況下,我們不需要傳遞,因為當Widgets 陳列出時, 是自動繼承父窗體的,但是Dock 窗體是個例外,因為它不是通過layouts 的方式來陳列的。
我們選擇限制這個客戶信息的Dock 窗體只能顯示在左邊和右邊的Dock區域。關于Dock區域的圖示,請看下圖:
用戶可以通過鼠標的拓展將Dock 移出,而變成一個自由窗體。通過QDockWidget::setFeatures()來設置Dock窗體是可移動的還是不可移動。
一旦我們創建好了Dock 窗體,創建好了list窗體,并指定list窗體的父窗體為Dock窗體,那么最后我們就可以調用addDockWidget()添加Dock 窗體到MainWindows 窗體中了。
我們依照同樣的過程可以創建另一個Dock 窗體,這次我們不限定該窗體的區域位置。
最后,我們通過信號槽事件。關聯信號currentTextChanged() ,到兩個槽 insertCustomer() ,addParagraph() 。
接著,我們來討論剩余的其他一些函數的實現。
void MainWindow::newLetter(){textEdit->clear();QTextCursor cursor(textEdit->textCursor());cursor.movePosition(QTextCursor::Start);QTextFrame *topFrame = cursor.currentFrame();QTextFrameFormat topFrameFormat = topFrame->frameFormat();topFrameFormat.setPadding(16);topFrame->setFrameFormat(topFrameFormat);QTextCharFormat textFormat;QTextCharFormat boldFormat;boldFormat.setFontWeight(QFont::Bold);QTextCharFormat italicFormat;italicFormat.setFontItalic(true);QTextTableFormat tableFormat;tableFormat.setBorder(1);tableFormat.setCellPadding(16);tableFormat.setAlignment(Qt::AlignRight);cursor.insertTable(1, 1, tableFormat);cursor.insertText("The Firm", boldFormat);cursor.insertBlock();cursor.insertText("321 City Street", textFormat);cursor.insertBlock();cursor.insertText("Industry Park");cursor.insertBlock();cursor.insertText("Some Country");cursor.setPosition(topFrame->lastPosition());cursor.insertText(QDate::currentDate().toString("d MMMM yyyy"), textFormat);cursor.insertBlock();cursor.insertBlock();cursor.insertText("Dear ", textFormat);cursor.insertText("NAME", italicFormat);cursor.insertText(",", textFormat);for (int i = 0; i < 3; ++i)cursor.insertBlock();cursor.insertText(tr("Yours sincerely,"), textFormat);for (int i = 0; i < 3; ++i)cursor.insertBlock();cursor.insertText("The Boss", textFormat);cursor.insertBlock();cursor.insertText("ADDRESS", italicFormat);}在該函數中,我們清空了QTextEdit。接著我們創建了一個QTextCursor ,我們移動光標到文檔的開始處,創建并格式化一個frame。 我們創建一些字符格式和一個表格格式。我們插入一個表格到文檔中,并參照上滿的格式插入公司名和地址到表格中。接著我們插入包含標記NAME和ADDRESS的郵件“骨架”,我們用“Yours sincerely”,也作為一個標記。
void MainWindow::insertCustomer(const QString &customer){if (customer.isEmpty())return;QStringList customerList = customer.split(", ");QTextDocument *document = textEdit->document();QTextCursor cursor = document->find("NAME");if (!cursor.isNull()) {cursor.beginEditBlock();cursor.insertText(customerList.at(0));QTextCursor oldcursor = cursor;cursor = document->find("ADDRESS");if (!cursor.isNull()) {for (int i = 1; i < customerList.size(); ++i) {cursor.insertBlock();cursor.insertText(customerList.at(i));}cursor.endEditBlock();}elseoldcursor.endEditBlock();}}如果用戶單擊了客戶信息的Dock, 會分割關于客戶的信息。然后我們查找標記“NAME”,在該標記中插入客戶的命名,同樣的,我們查找標記“ADDRESS”,并將此標記替代為客戶的地址。
值得注意的是:我們將所有的插入放置在beginEditBlock() 和endEditBlock() 這兩個函數之間。
該函數的功能類似于insertCustomer(). 首先我們尋找標記,這里的標記是“Yours sincerely”,然后在在標記前,插入單擊選中的段落文本。同樣的這里我們調用beginEditBlock() … endEditBlock()函數對,以便于我們撤銷時,把整段添加的都一并撤銷。
void MainWindow::print(){#if QT_CONFIG(printdialog)QTextDocument *document = textEdit->document();QPrinter printer;QPrintDialog dlg(&printer, this);if (dlg.exec() != QDialog::Accepted) {return;}document->print(&printer);statusBar()->showMessage(tr("Ready"), 2000);#endif}可以看到,Qt 的QTextDocument 類調用打印文檔也非常簡單。
void MainWindow::save(){QMimeDatabase mimeDatabase;QString fileName = QFileDialog::getSaveFileName(this,tr("Choose a file name"), ".",mimeDatabase.mimeTypeForName("text/html").filterString());if (fileName.isEmpty())return;QFile file(fileName);if (!file.open(QFile::WriteOnly | QFile::Text)) {QMessageBox::warning(this, tr("Dock Widgets"),tr("Cannot write file %1:\n%2.").arg(QDir::toNativeSeparators(fileName), file.errorString()));return;}QTextStream out(&file);QGuiApplication::setOverrideCursor(Qt::WaitCursor);out << textEdit->toHtml();QGuiApplication::restoreOverrideCursor();statusBar()->showMessage(tr("Saved '%1'").arg(fileName), 2000);}QTextEdit 提供輸出HTML格式的文檔。
void MainWindow::undo(){QTextDocument *document = textEdit->document();document->undo();}如果窗體的焦點放置在QTextEdit,可以通過撤銷功能來撤銷刪除之前添加的文本。
總結:
1、官方給定的示例對DockWidget 的使用做了簡單介紹。2、富文本的應用這里也有涉及到。3、按照該示例程序的介紹可以很好的訓練程序思維。總之,按部就班的學習示例程序是學好Qt的一項基本策略。
ps:翻譯有不當之處,請讀者們多多指點,本人純粹是為了項目和學習的需要,才斗膽拙筆成文。
總結
以上是生活随笔為你收集整理的Qt Dock Widgets 官方示例的翻译的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 使用Qt创建XML文档及XML文档的增删
- 下一篇: Qt 2D painting Demo