Chinaunix首页 | 论坛 | 博客
  • 博客访问: 4524313
  • 博文数量: 1148
  • 博客积分: 25453
  • 博客等级: 上将
  • 技术积分: 11949
  • 用 户 组: 普通用户
  • 注册时间: 2010-05-06 21:14
文章分类

全部博文(1148)

文章存档

2012年(15)

2011年(1078)

2010年(58)

分类: C/C++

2011-07-29 17:21:11

http://hxzon00.blog.163.com/blog/static/104892416200996998768/

  1. textedit源代码 -Qt学习笔记 -hxzon

  2. 头文件
  3. ======================================
  4. #ifndef TEXTEDIT_H
  5. #define TEXTEDIT_H
  6. #include <QMainWindow>
  7. #include <QMap>
  8. #include <QPointer>
  9. QT_FORWARD_DECLARE_CLASS(QAction)
  10. QT_FORWARD_DECLARE_CLASS(QComboBox)
  11. QT_FORWARD_DECLARE_CLASS(QFontComboBox)
  12. QT_FORWARD_DECLARE_CLASS(QTextEdit)
  13. QT_FORWARD_DECLARE_CLASS(QTextCharFormat)
  14. QT_FORWARD_DECLARE_CLASS(QMenu)
  15. class TextEdit : public QMainWindow
  16. {
  17.     Q_OBJECT
  18. public:
  19.     TextEdit(QWidget *parent = 0);
  20. protected:
  21.     virtual void closeEvent(QCloseEvent *e);
  22. private:
  23.     void setupFileActions();
  24.     void setupEditActions();
  25.     void setupTextActions();
  26.     bool load(const QString &f);
  27.     bool maybeSave();
  28.     void setCurrentFileName(const QString &fileName);
  29. private slots:
  30.     void fileNew();
  31.     void fileOpen();
  32.     bool fileSave();
  33.     bool fileSaveAs();
  34.     void filePrint();
  35.     void filePrintPreview();
  36.     void filePrintPdf();
  37.     void textBold();
  38.     void textUnderline();
  39.     void textItalic();
  40.     void textFamily(const QString &f);
  41.     void textSize(const QString &p);
  42.     void textStyle(int styleIndex);
  43.     void textColor();
  44.     void textAlign(QAction *a);
  45.     void currentCharFormatChanged(const QTextCharFormat &format);
  46.     void cursorPositionChanged();
  47.     void clipboardDataChanged();
  48.     void about();
  49.     void printPreview(QPrinter *);
  50. private:
  51.     void mergeFormatOnWordOrSelection(const QTextCharFormat &format);
  52.     void fontChanged(const QFont &f);
  53.     void colorChanged(const QColor &c);
  54.     void alignmentChanged(Qt::Alignment a);
  55.     QAction *actionSave,
  56.         *actionTextBold,
  57.         *actionTextUnderline,
  58.         *actionTextItalic,
  59.         *actionTextColor,
  60.         *actionAlignLeft,
  61.         *actionAlignCenter,
  62.         *actionAlignRight,
  63.         *actionAlignJustify,
  64.         *actionUndo,
  65.         *actionRedo,
  66.         *actionCut,
  67.         *actionCopy,
  68.         *actionPaste;
  69.     QComboBox *comboStyle;
  70.     QFontComboBox *comboFont;
  71.     QComboBox *comboSize;
  72.     QToolBar *tb;
  73.     QString fileName;
  74.     QTextEdit *textEdit;
  75. };
  76. #endif
  77. =============================================
  78. 初始化界面,添加各种事件
  79. --------------------
  80. 将textEdit的字体样式改变和光标位置改变信号转发给本实例。
  81.     textEdit = new QTextEdit(this);
  82.     connect(textEdit, SIGNAL(currentCharFormatChanged(const QTextCharFormat &)),
  83.             this, SLOT(currentCharFormatChanged(const QTextCharFormat &)));
  84.     connect(textEdit, SIGNAL(cursorPositionChanged()),
  85.             this, SLOT(cursorPositionChanged()));
  86.     setCentralWidget(textEdit);
  87.     textEdit->setFocus();
  88.     fontChanged(textEdit->font());
  89.     colorChanged(textEdit->textColor());
  90.     alignmentChanged(textEdit->alignment());
  91.     connect(textEdit->document(), SIGNAL(modificationChanged(bool)),
  92.             actionSave, SLOT(setEnabled(bool)));
  93.     connect(textEdit->document(), SIGNAL(modificationChanged(bool)),
  94.             this, SLOT(setWindowModified(bool)));
  95.     connect(textEdit->document(), SIGNAL(undoAvailable(bool)),
  96.             actionUndo, SLOT(setEnabled(bool)));
  97.     connect(textEdit->document(), SIGNAL(redoAvailable(bool)),
  98.             actionRedo, SLOT(setEnabled(bool)));
  99.     setWindowModified(textEdit->document()->isModified());
  100.     actionSave->setEnabled(textEdit->document()->isModified());
  101.     actionUndo->setEnabled(textEdit->document()->isUndoAvailable());
  102.     actionRedo->setEnabled(textEdit->document()->isRedoAvailable());
  103.     connect(actionUndo, SIGNAL(triggered()), textEdit, SLOT(undo()));
  104.     connect(actionRedo, SIGNAL(triggered()), textEdit, SLOT(redo()));
  105.     actionCut->setEnabled(false);
  106.     actionCopy->setEnabled(false);
  107.     connect(actionCut, SIGNAL(triggered()), textEdit, SLOT(cut()));
  108.     connect(actionCopy, SIGNAL(triggered()), textEdit, SLOT(copy()));
  109.     connect(actionPaste, SIGNAL(triggered()), textEdit, SLOT(paste()));
  110.     connect(textEdit, SIGNAL(copyAvailable(bool)), actionCut, SLOT(setEnabled(bool)));
  111.     connect(textEdit, SIGNAL(copyAvailable(bool)), actionCopy, SLOT(setEnabled(bool)));
  112.     connect(QApplication::clipboard(), SIGNAL(dataChanged()), this, SLOT(clipboardDataChanged()));
  113.     QString initialFile = ":/example.html";
  114.     const QStringList args = QCoreApplication::arguments();
  115.     if (args.count() == 2)
  116.         initialFile = args.at(1);
  117.     if (!load(initialFile))
  118.         fileNew();
  119. ---------------------------
  120.     QToolBar *tb = new QToolBar(this);//按钮条,本例不止一个按钮条
  121.     tb->setWindowTitle(tr("File Actions"));
  122.     addToolBar(tb);//窗体添加按钮条
  123.     QMenu *menu = new QMenu(tr("&File"), this);//file菜单
  124.     menuBar()->addMenu(menu);//菜单栏添加file菜单
  125.     QAction *a;
  126.     a = new QAction(QIcon(rsrcPath + "/filenew.png"), tr("&New"), this);//定义一个动作
  127.     a->setShortcut(QKeySequence::New);//快捷键
  128.     connect(a, SIGNAL(triggered()), this, SLOT(fileNew()));//监听,通过信号和槽链接//发射信号 emit triggered();
  129.     tb->addAction(a);//按钮条添加按钮项
  130.     menu->addAction(a);//file菜单添加菜单项
  131.     a = new QAction(QIcon(rsrcPath + "/fileopen.png"), tr("&Open..."), this);
  132.     a->setShortcut(QKeySequence::Open);
  133.     connect(a, SIGNAL(triggered()), this, SLOT(fileOpen()));//此菜单触发打开文件操作
  134.     tb->addAction(a);
  135.     menu->addAction(a);
  136.     menu->addSeparator();//file菜单添加分割线
  137. ----------------------------
  138. actionPaste->setEnabled(!QApplication::clipboard()->text().isEmpty());
  139. ----------------------------
  140.     actionTextBold = new QAction(QIcon(rsrcPath + "/textbold.png"), tr("&Bold"), this);
  141.     actionTextBold->setShortcut(Qt::CTRL + Qt::Key_B);
  142.     QFont bold;
  143.     bold.setBold(true);
  144.     actionTextBold->setFont(bold);//
  145.     connect(actionTextBold, SIGNAL(triggered()), this, SLOT(textBold()));
  146.     tb->addAction(actionTextBold);
  147.     menu->addAction(actionTextBold);
  148.     actionTextBold->setCheckable(true);//
  149. ---------------------------------
  150. 对齐操作
  151.     QActionGroup *grp = new QActionGroup(this);
  152.     connect(grp, SIGNAL(triggered(QAction *)), this, SLOT(textAlign(QAction *)));
  153.     // Make sure the alignLeft is always left of the alignRight
  154.     if (QApplication::isLeftToRight()) {
  155.         actionAlignLeft = new QAction(QIcon(rsrcPath + "/textleft.png"), tr("&Left"), grp);
  156.         actionAlignCenter = new QAction(QIcon(rsrcPath + "/textcenter.png"), tr("C&enter"), grp);
  157.         actionAlignRight = new QAction(QIcon(rsrcPath + "/textright.png"), tr("&Right"), grp);
  158.     } else {
  159.         actionAlignRight = new QAction(QIcon(rsrcPath + "/textright.png"), tr("&Right"), grp);
  160.         actionAlignCenter = new QAction(QIcon(rsrcPath + "/textcenter.png"), tr("C&enter"), grp);
  161.         actionAlignLeft = new QAction(QIcon(rsrcPath + "/textleft.png"), tr("&Left"), grp);
  162.     }
  163.     actionAlignJustify = new QAction(QIcon(rsrcPath + "/textjustify.png"), tr("&Justify"), grp);
  164.     actionAlignLeft->setShortcut(Qt::CTRL + Qt::Key_L);
  165.     actionAlignLeft->setCheckable(true);
  166.     actionAlignCenter->setShortcut(Qt::CTRL + Qt::Key_E);
  167.     actionAlignCenter->setCheckable(true);
  168.     actionAlignRight->setShortcut(Qt::CTRL + Qt::Key_R);
  169.     actionAlignRight->setCheckable(true);
  170.     actionAlignJustify->setShortcut(Qt::CTRL + Qt::Key_J);
  171.     actionAlignJustify->setCheckable(true);
  172.     tb->addActions(grp->actions());
  173.     menu->addActions(grp->actions());
  174. ------------------------------------
  175. //并列项样式
  176.     comboStyle = new QComboBox(tb);
  177.     tb->addWidget(comboStyle);
  178.     comboStyle->addItem("Standard");
  179.     comboStyle->addItem("Bullet List (Disc)");
  180.     comboStyle->addItem("Bullet List (Circle)");
  181.     comboStyle->addItem("Bullet List (Square)");
  182.     comboStyle->addItem("Ordered List (Decimal)");
  183.     comboStyle->addItem("Ordered List (Alpha lower)");
  184.     comboStyle->addItem("Ordered List (Alpha upper)");
  185.     connect(comboStyle, SIGNAL(activated(int)),
  186.             this, SLOT(textStyle(int)));
  187. //字体样式
  188.     comboFont = new QFontComboBox(tb);
  189.     tb->addWidget(comboFont);
  190.     connect(comboFont, SIGNAL(activated(const QString &)),
  191.             this, SLOT(textFamily(const QString &)));
  192. //字体大小
  193.     comboSize = new QComboBox(tb);
  194.     comboSize->setObjectName("comboSize");
  195.     tb->addWidget(comboSize);
  196.     comboSize->setEditable(true);
  197.     QFontDatabase db;
  198.     foreach(int size, db.standardSizes())
  199.         comboSize->addItem(QString::number(size));
  200.     connect(comboSize, SIGNAL(activated(const QString &)),
  201.             this, SLOT(textSize(const QString &)));
  202.     comboSize->setCurrentIndex(comboSize->findText(QString::number(QApplication::font()
  203.                                                                    .pointSize())));
  204. -----------------------------
  205. -----------------------------
  206. 事件响应操作:
  207. 关闭操作
  208. void TextEdit::closeEvent(QCloseEvent *e)
  209. {
  210.     if (maybeSave())
  211.         e->accept();
  212.     else
  213.         e->ignore();
  214. }
  215. 加载文件
  216. bool TextEdit::load(const QString &f)
  217. {
  218.     if (!QFile::exists(f))
  219.         return false;
  220.     QFile file(f);
  221.     if (!file.open(QFile::ReadOnly))
  222.         return false;
  223.     QByteArray data = file.readAll();
  224.     QTextCodec *codec = Qt::codecForHtml(data);
  225.     QString str = codec->toUnicode(data);
  226.     if (Qt::mightBeRichText(str)) {
  227.         textEdit->setHtml(str);
  228.     } else {
  229.         str = QString::fromLocal8Bit(data);
  230.         textEdit->setPlainText(str);
  231.     }
  232.     setCurrentFileName(f);
  233.     return true;
  234. }
  235. --------------------------
  236. 是否保存
  237. bool TextEdit::maybeSave()
  238. {
  239.     if (!textEdit->document()->isModified())
  240.         return true;
  241.     if (fileName.startsWith(QLatin1String(":/")))
  242.         return true;
  243.     QMessageBox::StandardButton ret;
  244.     ret = QMessageBox::warning(this, tr("Application"),
  245.                                tr("The document has been modified.\n"
  246.                                   "Do you want to save your changes?"),
  247.                                QMessageBox::Save | QMessageBox::Discard
  248.                                | QMessageBox::Cancel);
  249.     if (ret == QMessageBox::Save)
  250.         return fileSave();
  251.     else if (ret == QMessageBox::Cancel)
  252.         return false;
  253.     return true;
  254. }
  255. ----------------
  256. 新建文件
  257. void TextEdit::fileNew()
  258. {
  259.     if (maybeSave()) {
  260.         textEdit->clear();
  261.         setCurrentFileName(QString());
  262.     }
  263. }
  264. 打开文件,打开选择对话框
  265. void TextEdit::fileOpen()
  266. {
  267.     QString fn = QFileDialog::getOpenFileName(this, tr("Open File..."),
  268.                                               QString(), tr("HTML-Files (*.htm *.html);;All Files (*)"));
  269.     if (!fn.isEmpty())
  270.         load(fn);
  271. }
  272. 保存文件
  273. bool TextEdit::fileSave()
  274. {
  275.     if (fileName.isEmpty())
  276.         return fileSaveAs();
  277.     QTextDocumentWriter writer(fileName);
  278.     bool success = writer.write(textEdit->document());
  279.     if (success)
  280.         textEdit->document()->setModified(false);
  281.     return success;
  282. }
  283. 另存为,保存路径对话框
  284. bool TextEdit::fileSaveAs()
  285. {
  286.     QString fn = QFileDialog::getSaveFileName(this, tr("Save as..."),
  287.                                               QString(), tr("ODF files (*.odt);;HTML-Files (*.htm *.html);;All Files (*)"));
  288.     if (fn.isEmpty())
  289.         return false;
  290.     if (! (fn.endsWith(".odt", Qt::CaseInsensitive) || fn.endsWith(".htm", Qt::CaseInsensitive) || fn.endsWith(".html", Qt::CaseInsensitive)) )
  291.         fn += ".odt"; // default
  292.     setCurrentFileName(fn);
  293.     return fileSave();
  294. }
  295. -------------------
  296. 设置字体粗细
  297. void TextEdit::textBold()
  298. {
  299.     QTextCharFormat fmt;
  300.     fmt.setFontWeight(actionTextBold->isChecked() ? QFont::Bold : QFont::Normal);
  301.     mergeFormatOnWordOrSelection(fmt);
  302. }
  303. 设置并列项样式
  304. void TextEdit::textStyle(int styleIndex)
  305. {
  306.     QTextCursor cursor = textEdit->textCursor();
  307.     if (styleIndex != 0) {
  308.         QTextListFormat::Style style = QTextListFormat::ListDisc;
  309.         switch (styleIndex) {
  310.             default:
  311.             case 1:
  312.                 style = QTextListFormat::ListDisc;
  313.                 break;
  314.             case 2:
  315.                 style = QTextListFormat::ListCircle;
  316.                 break;
  317.             case 3:
  318.                 style = QTextListFormat::ListSquare;
  319.                 break;
  320.             case 4:
  321.                 style = QTextListFormat::ListDecimal;
  322.                 break;
  323.             case 5:
  324.                 style = QTextListFormat::ListLowerAlpha;
  325.                 break;
  326.             case 6:
  327.                 style = QTextListFormat::ListUpperAlpha;
  328.                 break;
  329.         }
  330.         cursor.beginEditBlock();
  331.         QTextBlockFormat blockFmt = cursor.blockFormat();
  332.         QTextListFormat listFmt;
  333.         if (cursor.currentList()) {
  334.             listFmt = cursor.currentList()->format();
  335.         } else {
  336.             listFmt.setIndent(blockFmt.indent() + 1);
  337.             blockFmt.setIndent(0);
  338.             cursor.setBlockFormat(blockFmt);
  339.         }
  340.         listFmt.setStyle(style);
  341.         cursor.createList(listFmt);
  342.         cursor.endEditBlock();
  343.     } else {
  344.         // ####
  345.         QTextBlockFormat bfmt;
  346.         bfmt.setObjectIndex(-1);
  347.         cursor.mergeBlockFormat(bfmt);
  348.     }
  349. }
  350. 设置颜色,打开颜色选择对话框
  351. void TextEdit::textColor()
  352. {
  353.     QColor col = QColorDialog::getColor(textEdit->textColor(), this);
  354.     if (!col.isValid())
  355.         return;
  356.     QTextCharFormat fmt;
  357.     fmt.setForeground(col);
  358.     mergeFormatOnWordOrSelection(fmt);
  359.     colorChanged(col);
  360. }
  361. 设置对齐样式,以组为单位
  362. void TextEdit::textAlign(QAction *a)
  363. {
  364.     if (a == actionAlignLeft)
  365.         textEdit->setAlignment(Qt::AlignLeft | Qt::AlignAbsolute);
  366.     else if (a == actionAlignCenter)
  367.         textEdit->setAlignment(Qt::AlignHCenter);
  368.     else if (a == actionAlignRight)
  369.         textEdit->setAlignment(Qt::AlignRight | Qt::AlignAbsolute);
  370.     else if (a == actionAlignJustify)
  371.         textEdit->setAlignment(Qt::AlignJustify);
  372. }
  373. --------------------
  374. 字体样式改变
  375. void TextEdit::currentCharFormatChanged(const QTextCharFormat &format)
  376. {
  377.     fontChanged(format.font());
  378.     colorChanged(format.foreground().color());
  379. }
  380. 光标位置改变
  381. void TextEdit::cursorPositionChanged()
  382. {
  383.     alignmentChanged(textEdit->alignment());
  384. }
  385. 剪贴板改变
  386. void TextEdit::clipboardDataChanged()
  387. {
  388.     actionPaste->setEnabled(!QApplication::clipboard()->text().isEmpty());
  389. }
  390. void TextEdit::fontChanged(const QFont &f)
  391. {
  392.     comboFont->setCurrentIndex(comboFont->findText(QFontInfo(f).family()));
  393.     comboSize->setCurrentIndex(comboSize->findText(QString::number(f.pointSize())));
  394.     actionTextBold->setChecked(f.bold());
  395.     actionTextItalic->setChecked(f.italic());
  396.     actionTextUnderline->setChecked(f.underline());
  397. }
  398. void TextEdit::colorChanged(const QColor &c)
  399. {
  400.     QPixmap pix(16, 16);
  401.     pix.fill(c);
  402.     actionTextColor->setIcon(pix);
  403. }
  404. 对齐样式改变
  405. void TextEdit::alignmentChanged(Qt::Alignment a)
  406. {
  407.     if (a & Qt::AlignLeft) {
  408.         actionAlignLeft->setChecked(true);
  409.     } else if (a & Qt::AlignHCenter) {
  410.         actionAlignCenter->setChecked(true);
  411.     } else if (a & Qt::AlignRight) {
  412.         actionAlignRight->setChecked(true);
  413.     } else if (a & Qt::AlignJustify) {
  414.         actionAlignJustify->setChecked(true);
  415.     }
  416. }
  417. ------------------------
  418. 改变样式,合并样式
  419. void TextEdit::mergeFormatOnWordOrSelection(const QTextCharFormat &format)
  420. {
  421.     QTextCursor cursor = textEdit->textCursor();
  422.     if (!cursor.hasSelection())
  423.         cursor.select(QTextCursor::WordUnderCursor);
  424.     cursor.mergeCharFormat(format);
  425.     textEdit->mergeCurrentCharFormat(format);
  426. }

阅读(2595) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~