1、菜单栏
添加菜单:
QMainWindow中的菜单栏是一个QMenuBar对象,可以通过设计模式下来给菜单栏添加菜单,菜单项也可以设置加速键,通过在给菜单文本添加(&加速键),而且子菜单上如果设置的加速键其实就快捷键,不用再使用alt键,直接输入对应键即为点击对应的菜单项。如下所示的文件菜单项的加速键为alt + f,菜单项新建的快捷键为n。
QMainWindow设计模式下还有一个动作编辑器和信号槽编辑器,如下所示,动作编辑器里每一行对应一个菜单项,双击动作编辑器里一行来设置对应菜单项的显示文本、对象名称、提示文本、图标、快捷键等。信号槽编辑器里可以添加菜单项的一些信号槽方法,比如菜单项点击信号triggered,也可以在动作编辑器里右键-转到槽来自动生成菜单项的信号槽方法。
添加资源文件:
上面在动作编辑器里设置菜单的图标是在当前项目的资源文件里寻找图标文件,添加图片资源文件的方法:右键项目添加QT资源文件,名称可以设置为myResource,路径选择当前项目所在,点击确定后会在选择的路径下生成qrc文件,将图片文件放到qrc文件所在目录或子目录下,在Qt Creator中打开qrc文档(右击qrc文件选择open in editor),点击添加按钮选择添加前缀,编辑前缀名如“/myImage”,再点击添加按钮选择添加文件,选择要添加的图片文件,最后ctrl+s保存即可。在项目中使用图片资源的时候使用路径":/myImage/imageFolder/imageName.png"即可。
使用代码来添加菜单:
在菜单的动作编辑器里有个Checkable选项,这是用来设置菜单项点击后显示一个对勾标志的,在代码中我们可以将菜单项添加到一个QActionGroup动作组中,使只有一个菜单项点击后显示对勾:
也可以向菜单栏添加一个其它类型的部件,通过继承QWidgetAction,然后重写createWidget方法,在其中返回要添加的部件,如下代码实现了一个包含一个标签和一个行编辑器的菜单项:
QWidget* MyAction::createWidget(QWidget* parent) { if(parent->inherits("QMenu")) //父部件不是菜单直接返回 return nullptr; QSplitter* splitter = new QSplitter(parent); QLabel* label = new QLabel; label->setText(QString::fromUtf8(u8"输入文本")); splitter->addWidget(label); QLineEdit* lineEidt = new QLineEdit; splitter->addWidget(lineEidt); return splitter; }
QObject::inherits(const char* className)方法用来测试当前对象是否是className类型对象或其派生类对象。
2、工具栏
QToolBar是工具栏类,在前面代码里可以看到往工具栏上添加项也是使用addAction()方法添加一个QAction。如果想要往工具栏上添加Button等类型的部件的话可以使用addWidget()方法。通过工具栏的属性可以对其进行设置:toolButtonStyle设置图标和文本显示(默认只显示图标)、movable设置状态栏是否可以移动、allowedArea设置允许停靠的位置、floatable设置是否可以悬浮。
3、状态栏
QStatusBar提供了一个水平条,用来显示状态信息,QMainWindow下默认有一个状态栏。状态信息分为3类,临时信息(超过一段时间后消失,出现在状态栏左边)、正常信息(如当前行号、页数,在状态栏左边显示,可能会被临时信息掩盖)、永久信息(如版本信息,在状态栏右边显示),调用showMessage方法来显示临时信息,一般使用addWidget方法添加一个QLabel到状态栏上显示正常信息,使用addPermanentWidget方法来添加一个QLabel来显示永久信息。
QMainWindow状态栏的最右端有一个QSizeGrip部件,它用来调整窗口的大小,可以使用状态栏的setSizeGripEnabled()方法来禁用它。
4、富文本编辑器
QTextEdit是一个富文本编辑器,QTextBrowser是其只读版本,QPlaintTextEdit是普通的纯文本编辑器。如下是对QTextEdit进行的操作和效果:
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); ui->textEdit->setText("test"); //设置文本后光标默认没有变化还是在首位 QTextCursor cursor = ui->textEdit->textCursor(); //获取光标 cursor.movePosition(QTextCursor::End); //移动光标到末尾 ui->textEdit->setTextCursor(cursor); //应用到当前编辑器 }
上面代码在使用setText设置编辑器文本后光标还是在首位,也可以直接使用光标的insertText()方法来插入文本,这样光标会直接改变:
Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget) { ui->setupUi(this); QTextCursor cursr = ui->textEdit->textCursor(); cursr.insertText("test"); }
Qt对富文本的处理分为编辑操作和只读操作,编辑操作使用基于光标(QTextCursor)的一些接口函数,文档(QTextDocument)的读取使用只读的分层次接口函数。富文本文档中包含框架(QTextFrame)、文本块(QTextBlock)、表格(QTextTable)、列表(QTextList)这几种元素,每种元素的格式使用对应的format类来表示,如框架格式QTextFrameFormat、文本块格式QTextBlockFormat,一个空文档包含了一个根框架,这个根框架又包含了一个空的文本块,在根框架中还可以再添加文本块、子框架等。QTextEdit默认包含了一个QTextCursor光标对象和一个QTextDocument文档对象。如下图所示:
如下是对富文本编辑器重新设置了框架的格式,运行程序可以发现只能在红色边框的中进行输入:
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); QTextDocument* document = ui->textEdit->document(); //获取富文本编辑器的文档对象 QTextFrame* rootFrame = document->rootFrame(); //获取文档的根框架 QTextFrameFormat format; //创建框架格式 format.setBorderBrush(Qt::red); //边界颜色 format.setBorder(4); //边界宽度 //format.setWidth(100); //高度 rootFrame->setFrameFormat(format); //设置根框架格式 }
下面是在上面代码的基础上,使用光标对象,在根框架中再添加了一个子框架:
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); QTextDocument* document = ui->textEdit->document(); //获取富文本编辑器的文档对象 QTextFrame* rootFrame = document->rootFrame(); //获取文档的根框架 QTextFrameFormat format; //创建框架格式 format.setBorderBrush(Qt::red); //边界颜色 format.setBorder(4); //边界宽度 //format.setWidth(100); //高度 rootFrame->setFrameFormat(format); //设置根框架格式 QTextFrameFormat frameFormat; frameFormat.setBackground(Qt::lightGray); //背景颜色 frameFormat.setMargin(10); //边距 frameFormat.setPadding(5); //填衬(边框和文本的间距) frameFormat.setBorder(2); frameFormat.setBorderStyle(QTextFrameFormat::BorderStyle_Dotted); //边框样式为虚线 QTextCursor cursor = ui->textEdit->textCursor(); //获取光标 cursor.insertFrame(frameFormat); //在光标处插入子框架 }
下面的函数中获取了上面程序中的富文本编辑器的文档的根框架,然后遍历了根框架中所有子框架和文本块:
void MainWindow::on_pushButton_2_clicked() { QTextDocument* document = ui->textEdit->document(); //获取富文本编辑器的文档对象 QTextFrame* frame = document->rootFrame(); //获取文档的根框架 for(QTextFrame::iterator it = frame->begin(); !it.atEnd(); ++it) //遍历根框架的文档 { QTextFrame* childFrame = it.currentFrame(); //子框架 QTextBlock childBlock = it.currentBlock(); //文本块 qDebug() << childBlock.text(); } }