day4
完善记事本
复习用ui设计师模式设计简易记事本。
在之前的记事本基础上,增加功能–点击find按钮弹出对话框,在lineedit中输入信息,可以在文本中查找相应内容。还能勾选是否区分大小写和是否前向查找。
首先,右键点击工程,添加新文件。我们再添加一个QT设计师界面类,命名为dialog,创建好后自动添加头文件和源文件。
在对话框中,我们需要实现非模态对话框,当lineedit中没有文本时find按钮disable,按下find按钮判断checkbox选择发送向前查找或向后查找的信号,是否区分大小写则用系统提供的宏创建变量当做参数传递给mainwindow。
所以,dialog头文件中,声明两个槽函数和两个信号
signals:
void findNext(const QString &str,Qt::CaseSensitivity cs);//cs区分大小写信号参数,str要检索的字符串信息
void findPrevious(const QString //前向查找
&str,Qt::CaseSensitivity cs);
private slots:
void on_lineEdit_textChanged(const QString &arg1);
void on_pushButton_clicked();
dialog.cpp源文件中实现两个槽函数
void Dialog::on_lineEdit_textChanged(const QString &arg1)
{
ui->pushButton->setEnabled(!arg1.isEmpty());//直接判断,lineedit非空使能find按钮
}
void Dialog::on_pushButton_clicked()
{
QString str=ui->lineEdit->text();
//当区分大小写字母checkbox勾上时,cs=Qt::CaseSensitive,大小写敏感
Qt::CaseSensitivity cs=ui->checkBox->isChecked() ? Qt::CaseSensitive : Qt::CaseInsensitive;
if(ui->checkBox_2->isChecked())//向前查找的checkbox是否勾上
{
emit findPrevious(str,cs);//发送信号str和cs
}else{
emit findNext(str,cs);
}
}
在主窗口mainwindow中,包含上一步创建的对话框头文件dialog.h。当我们点击find按钮弹出对话框,由我们和对话框交互后,再告诉主窗口查找时要不要区分大小写、向前向后查找。因此,我们在mainwindow.h中声明三个槽函数,分别实现按下find按钮后弹出对话框、向前查找、向后查找的功能。
private slots:
void findP(const QString &str,Qt::CaseSensitivity cs);
void findN(const QString &str,Qt::CaseSensitivity cs);
void on_actionFind_triggered();
实现find按钮弹出对话框
void MainWindow::on_actionFind_triggered()
{
//模态对话框
/*
Dialog dialog(this);
dialog.exec(); //在这里对dialog进行事件循环,除非dialog被关闭,否则程序不会继续前进
*/
static Dialog *dialog=0;
if(dialog==0)
{
dialog=new Dialog(this);
connect(dialog,SIGNAL(findPrevious(QString,Qt::CaseSensitivity)),this,SLOT(findP(QString,Qt::CaseSensitivity)));
connect(dialog,SIGNAL(findNext(QString,Qt::CaseSensitivity)),this,SLOT(findN(QString,Qt::CaseSensitivity)));
}
dialog->show(); //show出来的是非模态对话框
}
实现向前和向后查找的槽函数,需要用到系统自带的find函数
void MainWindow::findP(const QString &str, Qt::CaseSensitivity cs)
{
QTextDocument::FindFlags flag=0;//用于系统自带的find的标志位信息,表示大小写、向前向后查找等
if(cs==Qt::CaseSensitive)//判断对话框传来的cs参数
{
flag|=QTextDocument::FindCaseSensitively;
}//设置好标志位
if(ui->centralTextEdit->find(str,flag))//如果找到了,高亮显示
activateWindow();
}
void MainWindow::findN(const QString &str, Qt::CaseSensitivity cs)
{
QTextDocument::FindFlags flag=QTextDocument::FindBackward;
if(cs==Qt::CaseSensitive)
{
flag|=QTextDocument::FindCaseSensitively;
}
if(ui->centralTextEdit->find(str,flag))
activateWindow();
}
注:槽与信号参数对应,类型个数对应,信号传的参数个数不能少于槽需要的参数个数
补充实验
- 简易图片查看器(可以打开一张图片并显示)
复习创建菜单,添加动作,获取文件名的知识点。
创建菜单需要
void addMenu();//用来创建菜单
QMenu *fileMenu;//声明一个菜单项“文件”
添加动作需要
void addActions();//用来把动作绑定到菜单中
QAction *open;
用一个槽函数来获取文件名,并显示图片
private slots:
void openfile();
同时声明一个标签label,把标签作为主窗口部件,然后在标签上打开图片的映射
QLabel *label;
头文件编辑完,我们补充源文件,首先构造函数里分配内存,设置主窗口,调用添加动作,添加菜单的函数。
label=new QLabel;
setCentralWidget(label);
addActions();
addMenu();
添加动作
void MainWindow::addActions()
{
open=new QAction("openpicture");
connect(open,SIGNAL(triggered()),this,SLOT(openfile()));
}
添加菜单
void MainWindow::addMenu()
{
fileMenu=menuBar()->addMenu("File");
fileMenu->addAction(open);
}
实现槽函数,获取文件名,显示图片
void MainWindow::openfile()
{
//QFileDialog::getOpenFileName(this)弹出模态对话框,返回一个文件名,用filename接收
QString filename=QFileDialog::getOpenFileName(this);
if(filename.isEmpty())
return;
QPixmap pixmap(filename);//像素图片的映射
label->setPixmap(pixmap);
adjustSize();//自动调整大小
}
- 简易播放器
新建mainwindow项目
在之前的实验中,我们用到的都是QT的core和gui,播放文件还需要multimediawidgets和multimedia。
pro文件中要加
QT += core gui
//改为,增加屏幕和播放器
QT += core gui multimediawidgets multimedia
省略与简易图片查看器相同的步骤,openfile槽函数,菜单,动作。
额外需要一个屏幕,一个媒体播放器,添加相应头文件
#include <QMediaPlayer>
#include <QVideoWidget>
//class MainWindow : public QMainWindow中声明public成员
QVideoWidget *videoWidget;
QMediaPlayer mediaPlayer;//没有*号
.cpp源文件,构造函数里步骤与简易图片查看器相同
videoWidget=new QVideoWidget;
mediaPlayer.setVideoOutput(videoWidget);//直接用.访问
setCentralWidget(videoWidget);
addActions();
addMenus();
添加菜单,动作,槽函数都大致相同。
槽函数略有不同在于获取文件名后直接播放
void MainWindow::openfile()
{
//打开模态对话框
QString filename=QFileDialog::getOpenFileName(this);
if(filename.isEmpty())
return;
mediaPlayer.setMedia(QUrl::fromLocalFile(filename));//通过.访问
mediaPlayer.play();
}
拓展知识
参考
根据信号的参数,QT自动匹配到相应的槽函数,类似C++的动态绑定。
我们不能在函数指针中使用函数参数的默认值。这是 C++ 语言的限制:参数默认值只能使用在直接地函数调用中。当使用函数指针取其地址的时候,默认参数是不可见的!