项目文件:
//main.cpp// #include <QtGui> #include "mainwindow.h" //! [0] int main(int argc,char* argv[]) { Q_INIT_RESOURCE(schema); QApplication app(argc,argv); MainWindow* const window = new MainWindow; window->show(); return app.exec(); } //! [0]
//mainwindow.h// #ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #if defined(Q_WS_MAEMO_5) || defined(Q_WS_SIMULATOR) #include "ui_schema_mobiles.h" #else #include "ui_schema.h" #endif //! [0] class MainWindow : public QMainWindow,private Ui::SchemaMainWindow { Q_OBJECT public: MainWindow(); private Q_SLOTS: void schemaSelected(int index); void instanceSelected(int index); void validate(); void textChanged(); private: void moveCursor(int line,int column); }; //! [0] #endif
//mainwindow.cpp// #include <QtGui> #include <QtXmlPatterns> #include "mainwindow.h" #include "xmlSyntaxHighlighter.h" //! [4] class MessageHandler : public QAbstractMessageHandler { public: MessageHandler() : QAbstractMessageHandler(0) { } QString statusMessage() const { return m_description; } int line() const { return m_sourceLocation.line(); } int column() const { return m_sourceLocation.column(); } protected: virtual void handleMessage(QtMsgType type,const QString &description,const QUrl &identifier,const QSourceLocation &sourceLocation) { Q_UNUSED(type); Q_UNUSED(identifier); m_messageType = type; m_description = description; m_sourceLocation = sourceLocation; } private: QtMsgType m_messageType; QString m_description; QSourceLocation m_sourceLocation; }; //! [4] //! [0] //窗口的构造函数 MainWindow::MainWindow() { setupUi(this); //XmlSyntaxHighlighter XML语法亮色 new XmlSyntaxHighlighter(schemaView->document()); new XmlSyntaxHighlighter(instanceEdit->document()); schemaSelection->addItem(tr("Contact Schema")); schemaSelection->addItem(tr("Recipe Schema")); schemaSelection->addItem(tr("Order Schema")); instanceSelection->addItem(tr("Valid Contact Instance")); instanceSelection->addItem(tr("Invalid Contact Instance")); //信号与槽的关联connect(添加触发目标,发射信号,接收槽函数) connect(schemaSelection,SIGNAL(currentIndexChanged(int)),SLOT(schemaSelected(int))); connect(instanceSelection,SLOT(instanceSelected(int))); connect(validateButton,SIGNAL(clicked()),SLOT(validate())); connect(instanceEdit,SIGNAL(textChanged()),SLOT(textChanged())); //setAlignment文本设置 对齐 validationStatus->setAlignment(Qt::AlignCenter | Qt::AlignVCenter); schemaSelected(0); instanceSelected(0); } //! [0] //! [1] void MainWindow::schemaSelected(int index) { //清空选择项,按index添加选择项 instanceSelection->clear(); if (index == 0) { instanceSelection->addItem(tr("Valid Contact Instance")); instanceSelection->addItem(tr("Invalid Contact Instance")); } else if (index == 1) { instanceSelection->addItem(tr("Valid Recipe Instance")); instanceSelection->addItem(tr("Invalid Recipe Instance")); } else if (index == 2) { instanceSelection->addItem(tr("Valid Order Instance")); instanceSelection->addItem(tr("Invalid Order Instance")); } textChanged(); //定义QFile,XSD格式 QFile schemaFile(QString(":/schema_%1.xsd").arg(index)); //以只读方式打开 schemaFile.open(QIODevice::ReadOnly); //转换UTF8编码 const QString schemaText(QString::fromUtf8(schemaFile.readAll())); //控件设置内容 schemaView->setPlainText(schemaText); validate(); } //! [1] //! [2] void MainWindow::instanceSelected(int index) { QFile instanceFile(QString(":/instance_%1.xml").arg((2*schemaSelection->currentIndex()) + index)); instanceFile.open(QIODevice::ReadOnly); const QString instanceText(QString::fromUtf8(instanceFile.readAll())); instanceEdit->setPlainText(instanceText); validate(); } //! [2] //! [3] void MainWindow::validate() { //按UTF8的格式 赋值内容给 QByteArray,const QByteArray schemaData = schemaView->toPlainText().toUtf8(); const QByteArray instanceData = instanceEdit->toPlainText().toUtf8(); MessageHandler messageHandler; //如果没猜错:这个就是XML格式分析错误用的 QXmlSchema schema; schema.setMessageHandler(&messageHandler); //加载XML规则格式 schema.load(schemaData); bool errorOccurred = false; if (!schema.isValid()) { errorOccurred = true; } else { QXmlSchemaValidator validator(schema); if (!validator.validate(instanceData)) errorOccurred = true; } if (errorOccurred) { validationStatus->setText(messageHandler.statusMessage()); moveCursor(messageHandler.line(),messageHandler.column()); } else { validationStatus->setText(tr("validation successful")); } const QString styleSheet = QString("QLabel {background: %1; padding: 3px}") .arg(errorOccurred ? QColor(Qt::red).lighter(160).name() : QColor(Qt::green).lighter(160).name()); //更新样式 validationStatus->setStyleSheet(styleSheet); } //! [3] void MainWindow::textChanged() { //设置选中行 instanceEdit->setExtraSelections(QList<QTextEdit::ExtraSelection>()); } void MainWindow::moveCursor(int line,int column) { /** *有人会很觉得很奇怪为何没有明细选择数据那到那 *其实代码是:光标在那,就设置那行的样式 **/ //moveCursor移动光标 instanceEdit->moveCursor(QTextCursor::Start); for (int i = 1; i < line; ++i) instanceEdit->moveCursor(QTextCursor::Down); for (int i = 1; i < column; ++i) instanceEdit->moveCursor(QTextCursor::Right); //由于需要使用列表装载数据进行处理 //定义控件中的额外选择项 QList<QTextEdit::ExtraSelection> extraSelections; QTextEdit::ExtraSelection selection; //定义红色 //设置属性集的背景色 //设置属性集的长度 //获取光标位置 //清除选择行意义不明 //添加的List容器 const QColor lineColor = QColor(Qt::red).lighter(160); selection.format.setBackground(lineColor); selection.format.setProperty(QTextFormat::FullWidthSelection,true); selection.cursor = instanceEdit->textCursor(); selection.cursor.clearSelection(); extraSelections.append(selection); //更新选择内容 instanceEdit->setExtraSelections(extraSelections); instanceEdit->setFocus(); }
挺有趣的