Qt练手项目:简单的记事本小软件

来几张效果图吧:

Qt练手项目:简单的记事本小软件Qt练手项目:简单的记事本小软件Qt练手项目:简单的记事本小软件

小软件的主要功能包括:

新建文件,打开文件,保存文件,文件另存为

撤销,重做

复制,剪切,粘贴

改变字体,改变字体颜色

第一部分:

一个一个慢慢说。首先是软件的基本界面,有了界面再添加功能。构成界面的主体就是菜单栏,工具栏和文本区域。

菜单栏:

QMenu *fileMenu;QMenu *editMenu;QMenu *helpMenu;

上面代码声明三个菜单项,然后再添加到菜单栏,Qt里一个menuBar()函数返回主窗口的菜单栏。也可以像下面这样用QMenuBar声明一个菜单栏:

QMenuBar *menuBar = new QMenuBar(0);

因为我是直接在MainWindow窗口直接写的代码,就用menuBar()函数了。将菜单项添加到菜单栏:

//实例化fileMenu = new QMenu(this);//this指当前窗口editMenu = new QMenu(this);helpMenu = new QMenu(this);//添加到菜单栏并命名fileMenu = menuBar()->addMenu("File");editMenu = menuBar()->addMenu("Edit");helpMenu = menuBar()->addMenu("Help");

在每个菜单项下面有好几个功能,比如File菜单下有新建,打开,保存,另存为,打印,退出功能,在Qt里每一个功能作为一个动作,即QAction,这与java不同,java里每一个菜单项的子项是menuItem。声明子菜单项(以File菜单为例):

QAction *newAct; //新建QAction *openAct; //打开QAction *saveAct; //保存QAction *saveAsAct; //另存为QAction *printAct; //打印QAction *quitAct; //退出

在Edit,Help菜单下的那些子项也像上面那样声明就行了,这里就不贴代码里。接下来就是实例化每一个动作,以newAct为例:

newAct = new QAction(QIcon("Images/newFile"),"New",this);newAct->setShortcut(QKeySequence(Qt::CTRL Qt::Key_N));newAct->setStatusTip("New File");

上面三行代码中,第一句实例化一个动作,第一个参数设置它的Icon,即图标,第二个参数是名字,第三个参数是父对象,this指当前窗口。函数原型如下:

QAction(const QIcon & icon, const QString & text, QObject * parent)

第二句代码设置快捷键。第三行代码设置状态栏信息,状态栏在软件的下面,当鼠标停在该动作上时在状态栏左边显示的信息。

接下来就是把这些action添加到菜单项下面。addAction()函数负责完成这个功能,如下:

fileMenu->addAction(newAct);fileMenu->addSeparator();fileMenu->addAction(openAct);

addSeparator()函数是在两个动作之间加一条分割线。

依葫芦画瓢其他的一些菜单子项也是这么个步骤,不再详述。接下来是工具栏。

工具栏

当新建工程时主窗口是自带工具栏的,那便是mainToolBar,所以不必另外再定义新的工具栏,直接在它上面添加动作就行了。添加动作和添加分割线的函数与菜单栏一样,示例代码如下:

ui->mainToolBar->addAction(newAct);ui->mainToolBar->addSeparator();

文本区域

文本区域我用的是QTextEdit类,该类提供一个用来显示和编辑文本的部件,这个类的强大之处是我们平常用的那些操作文本的快捷键它都用实现了,不用自己再写代码。如复制文本Ctrl C,粘贴文本Ctrl V,剪贴文本Ctrl X。主要代码如下:

QTextEdit *textEdit;textEdit = new QTextEdit();textEdit->setFont(QFont("宋体", 15));//设置默认字体:字体,字体大小setCentralWidget(textEdit);//设置文本区域为整个窗口的中央部件

当我们用notepad编辑器的时候,软件右下角会显示鼠标光标所在的行数和列数,这里也实现了这个功能。首先声明一个Label层用来显示信息,然后再把Label添加到状态栏。

QLabel *textInfo;textInfo = new QLabel();textInfo->setText("Ready");//设置默认显示内容statusBar()->addPermanentWidget(textInfo);//添加到状态栏,在软件右下角

statusBar()函数获取主窗口的状态栏,addPermanentWidget()函数添加永久性部件,永久性意味着它不会被临时信息所覆盖,添加到状态栏右边。刚才在菜单栏设置每个动作的信息时,显示的信息是在状态栏左边。然后就是写一个函数获得鼠标光标的位置信息,并把信息显示在Label上。

void MainWindow::showTextInfo(){QTextCursor textCursor = textEdit->textCursor();//获得鼠标光标int lineNum = textCursor.blockNumber();//行数int colNum = textCursor.columnNumber();//列数textInfo->setText(tr("Li:%1,Col:%2").arg(lineNum 1).arg(colNum));//显示在Label上,注意:行数是从0开始的}

最后,也是最重要的一步,谁来调用这个函数?我们怎么知道鼠标光标的位置改变了呢?这就要说到Qt最厉害的地方了,信号与槽。简单来说:槽就是响应函数,信号就是给响应函数发的消息,意思是这个消息一产生,相应的函数就要执行。就像电影《集结号》里,集结的号声一响你就可以撤退了,这里号声就是信号,撤退就是槽。一行代码如下:

【文章福利】Qt开发学习资料包、大厂面试题、技术视频和学习路线图,包括(Qt C 基础,数据库编程,Qt项目实战、Qt框架、QML、Opencv、qt线程等等)有需要的可以进企鹅裙937552610领取哦~

connect(textEdit,SIGNAL(cursorPositionChanged()),this,SLOT(showTextInfo()));

函数原型:

QObject::connect(const QObject * sender, const char * signal, const QObject * receiver,const char * method, Qt::ConnectionType type = Qt::AutoConnection)

参数说明:

const QObject * sender :发出信号的对象

const char * signal : 信号

const QObject * receiver : 接收信号的对象

const char * method : 槽

Qt::ConnectionType type = Qt::AutoConnection : 连接方式,已经设定为自动连接了,多数情况下不用考虑这个参数

在我们那行代码里,发出信号的对象是文本区域,即textEdit,信号是鼠标光标的位置变了,cursorPositionChanged()函数返回这个信息,这个函数式Qt提供的,接收信号的对象是当前主窗口,槽就是showTextInfo()函数,实时改变状态栏右下角的信息。

第二部分

各个功能的实现。菜单栏一共就三个选项File,Edit,Help,一个一个说。

Edit

Edit菜单项下面有五个子项(动作),分别是:

Undo :撤销

Redo :重做

Cut :剪切

Copy :复制

Paste :粘贴

这些功能Qt里都提供了函数实现,所以这部分功能就是连接信号与槽就行了,并且那些快捷键操作Qt也实现了。代码如下:

//头文件定义槽private slots:void slotCut();void slotCopy();void slotPaste();void slotRedo();void slotUndo();//源文件实现槽,并与信号连接void MainWindow::slotCut(){textEdit->cut();}void MainWindow::slotCopy(){textEdit->copy();}void MainWindow::slotPaste(){textEdit->paste();}void MainWindow::slotRedo(){textEdit->redo();}void MainWindow::slotUndo(){textEdit->undo();}//连接信号与槽connect(undoAct,SIGNAL(triggered()),this,SLOT(slotUndo()));connect(redoAct,SIGNAL(triggered()),this,SLOT(slotRedo()));connect(cutAct,SIGNAL(triggered()),this,SLOT(slotCut()));connect(copyAct,SIGNAL(triggered()),this,SLOT(slotCopy()));connect(pasteAct,SIGNAL(triggered()),this,SLOT(slotPaste()));

刚开始我并不知道Qt提供了这些函数,就自己写了复制和粘贴的函数,当写剪切的函数时,看文档发现Qt已经实现了这些个函数,就拿来用吧。有现成的轮子何必再自己造轮子呢!把自己写的那两个函数的代码也贴上来吧:

void MainWindow::slotCopy(){QTextCursor cur = textEdit->textCursor();//返回当前光标对象copyText = cur.selectedText();//coptText是一个全局QString对象,获取鼠标选中的文本}void MainWindow::slotPaste(){textEdit->textCursor().insertText(copyText);//在鼠标光标处插入刚才复制的文本}Help

Help菜单项就一个子菜单–about,弹出一个消息窗口,上面显示一些我想说的信息。它的动作名是aboutAct。槽是actAboutAuthor()函数。

void MainWindow::actAboutAuthor(){QMessageBox::about(this,"About","Thissoftware wasmade By DJ.");}connect(aboutAct,SIGNAL(triggered()),SLOT(actAboutAuthor()));

File

File菜单下有六个子项

New :新建

Open :打开

Save :保存

Save As :另存为

Print :打印,这个功能是调用打印机的,没实现

Quit :退出程序

当要新建,打开其他文件或退出程序时,需要判断当前的文件内容是不是被修改了,如果被修改了,就要提醒用户是不是要保存当前文件,所以需要一个函数来返回这个信息。函数如下:

bool MainWindow::maybeSave(){if(textEdit->document()->isModified()){//判断文件是否被修改QMessageBox::StandardButtons result;result = QMessageBox::warning(this,"Waring","Do you want to save the file?",QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel);if(result == QMessageBox::Cancel){//取消return false;}if(result == QMessageBox::Save){//保存return slotSave();}if(result == QMessageBox::Discard){//忽略,即不保存return true;}}else{return true;}}

当保存文件时,还要判断这个文件是不是存在,如果存在直接保存就好,如果不存在,就要新建一个文件再保存,相当于另存为了。currentFile是全局QString变量,指当前的文件名,如果为空说明需要另外建一个文件保存当前文本信息,就调用另存为的响应函数;非空就直接在当前文件下保存内容。

bool MainWindow::slotSave(){if(currentFile.isEmpty()){return slotSaveAs();} else{return saveFile(currentFile);}}

另存为的槽函数如下,getSaveFileName()函数弹出文件保存对话框并返回文件名。第三个参数是默认路径和默认文件名,第四个参数是文件过滤器。如果是一个过滤器多个文件的话,文件后缀以空格分开,如:

"Image Files (*.png *.jpg *.bmp)" ;

如果是多个过滤器的话,过滤器之间用两个分号隔开,如

"Images (*.png *.xpm *.jpg);;Text files (*.txt);;XML files (*.xml)"

槽函数代码如下:

bool MainWindow::slotSaveAs(){QString fileName =QFileDialog::getSaveFileName(this,tr("Save As"),"/home/mary",tr("Text Files (*.txt)"));if(fileName.isEmpty()){return false;}else{return saveFile(fileName);}}

saveFile()函数代码如下:

bool MainWindow::saveFile(QString fileName){QFile file(fileName);if(!file.open(QFile::WriteOnly | QFile::Text)){QMessageBox::critical(this,"critical","cannot write file");return false;}else{QTextStream out(&file);out<<textEdit->toPlainText();setFileName(fileName);return true;}}

新建文件的槽函数如下:

void MainWindow::slotNew(){if(maybeSave()){textEdit->clear();setFileName("");}}void MainWindow::setFileName(QString fileName){currentFile = fileName;textEdit->document()->setModified(false);this->setWindowModified(false);fileName.isEmpty() ?this->setWindowFilePath("new.txt") :this->setWindowFilePath(fileName);}

打开文件的槽函数如下:

void MainWindow::slotOpen(){if(maybeSave()){QString fileName = QFileDialog::getOpenFileName(this);if(!fileName.isEmpty()){loadFile(fileName);}}}//加载文件的函数void MainWindow::loadFile(QString fileName){QFile file(fileName);if(!file.open(QFile::ReadOnly | QFile::Text)){QMessageBox::critical(this,"critical","cannot read file");}else{QTextStream in(&file);textEdit->setText(in.readAll());setFileName(fileName);}}

退出程序的槽函数如下:

void MainWindow::quitApp(){if(maybeSave()){qApp->closeAllWindows();//关闭所有窗口}}

说到退出程序,还有另外一个情况要考虑,如果用户直接点击软件右上角的X号关闭软件的话,如果文本内容改变了也要提醒他是否要保存文本,这就要用到Qt的事件机制,写一个函数,参数是关闭事件。代码如下:

void MainWindow::closeEvent(QCloseEvent *e){if(maybeSave()){e->accept();}else{e->ignore();//忽略,直接关闭}}

呼呼~终于写完了大部分了,我都写了三个小时了。~~(>_<)~~

第三部分

还有另外两个功能要说一下,工具栏上的更改字体和更改颜色的工能。Qt真是方便啊,它又提供了字体选择和颜色选择面板(好吧,java swing也提供了,而且颜色面板更丰富)。主要代码如下:

void MainWindow::changeFontFamily(){QFontDialog fontDlg; //字体选择对话框,可以选择字体,字体样式,大小QFont font;bool isChanged;font = fontDlg.getFont(&isChanged);if(isChanged){textEdit->setFont(font);}}void MainWindow::changeFontColor(){QColorDialog colorDlg; //颜色选择对话框QColor color;QPalette palette = textEdit->palette();//获得文本区域的调色板color = colorDlg.getColor(Qt::black);//默认是黑色if (color.isValid()){palette.setColor(QPalette::Text, color);//设置字体颜色textEdit->setPalette(palette);}}

这里有必要说一下QPalette类,在Qt里每一个控件都有一个调色板,它控制着控件的所有颜色信息。对于文本区域QTextEdit控件,目前我知道两种颜色分量,字体颜色和背景颜色,值分别是QPalette::Text 和 QPalette::Base。所有,其实软件还可以增加一个小功能:改变文本区域的背景颜色。

来两张图片吧:

Qt练手项目:简单的记事本小软件Qt练手项目:简单的记事本小软件

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

(0)
上一篇 2024年4月24日 上午10:05
下一篇 2024年4月24日 上午10:17

相关推荐

  • 科研项目管理SOP

    科研项目管理SOP 科研项目管理是一个非常重要的领域,它涉及到项目的规划、执行、评估和收尾。因此,确保科研项目管理遵循标准化流程非常重要。本文将介绍科研项目管理中的标准化流程,包括…

    科研百科 2024年10月12日
    25
  • 软件三级等保测评是什么?有哪些内容和要求?(软件三级等保测评是什么-有哪些内容和要求呢)

    一、什么是等保三级 等级保护三级又称中国信息安全等级保护三级认证,是中国最权威的信息产品安全等级资格认证,由公安机关根据国家信息安全保护规章和有关制度,按照管理规范和标准,对各机构…

    科研百科 2024年5月21日
    83
  • 项目管理jira

    项目管理jira 在信息技术行业中,项目管理已经成为了一种非常普遍的方法。这种方法可以帮助组织更好地管理其项目,提高项目完成的效率和质量。在项目管理中,Jira是一个常用的项目管理…

    科研百科 2024年7月25日
    33
  • 雪之平为啥被国家禁止了

    雪之平为啥被国家禁止了 最近,雪之平(Snow White)这个虚构的角色因为被禁止了而引起了广泛的关注和讨论。那么,雪之平被禁止的原因是什么呢? 雪之平是一个经典的虚构角色,她是…

    科研百科 2024年10月26日
    34
  • 达闼

    达闼: 探索未知世界的勇气 在这个世界上,有许多我们未知的地方,有许多我们不知道的事情。这些地方和事情需要我们有探索未知世界的勇气。 达闼是一位探险家,他有着一颗好奇心和冒险精神。…

    科研百科 2024年12月4日
    0
  • 最新2022年PMP项目管理考试官方具体时间安排(pmp项目管理资格考试时间)

    PMP每年有4次考试,分别在3月,6月,9月和12月,最近的一次考试是2022年6月25日和2022年7月30日举办的考试。 除北京和上海地区外,是在2022年6月25日上午举办的…

    科研百科 2024年2月21日
    115
  • 中医科研课题公示(中医药科研项目的公示栏)

    中医药科研项目的公示栏 尊敬的各位科学家、工程师、医生和研究人员: 本公示旨在向大家介绍我们的中医药科研项目,并就项目的进展情况进行公示。 项目名称:中医药治疗癌症的研究 项目背景…

    科研百科 2024年8月2日
    50
  • 进度计划编制软件免费

    进度计划编制软件免费:让工作更高效 随着现代商业的快速发展,进度计划编制软件已经成为了企业日常运营中不可或缺的一部分。但是,对于很多人来说,购买和安装一款软件并不容易,甚至免费的软…

    科研百科 2024年9月27日
    26
  • 联出党建“朋友圈”,共绘振兴“同心圆”(党建朋友圈文案)

    “前几天,一个莱芜的客户来我们村收花椒,价格合适,但是我们村的花椒数量不够。能不能咱们两村各出一部分?”近日,钢城区南部新城东峪村的孙建来到灰菜峪村,商量今年无刺花椒的销售问题。最…

    科研百科 2024年7月18日
    38
  • http120.35.30.189entwebpageslogin.jsp

    login.jsp 在网站或应用程序中,登录页面通常是用户进入系统的第一步。这个页面需要用户输入他们的用户名和密码,以验证他们的身份,并将他们带到正确的页面或操作。 然而,在现实生…

    科研百科 2024年10月4日
    17