Qt之主窗口(二)


主窗口编程
3.1 解决Bug----打开文件时,如何没有选择任何文件,程序仍然会打开1个空文件,这是不对的
解决办法:
要检查getOpenFileName函数的返回值是否为空,如果为空,后面的代码就不用被执行了
代码:
void Edit001MainWindow::on_actionOpen_triggered()
{
    QString fileName=QFileDialog::getOpenFileName(this,"打开文件","/root/lianxi_qt");
    if(fileName.isEmpty())
    {
        return;
    }
    MyTextEdit *myTextEdit=new MyTextEdit;
    QMdiSubWindow *mdiSubWindow=mdiArea->addSubWindow(myTextEdit);
    myTextEdit->loadFile(fileName);
    mdiSubWindow->show();
}


3.2 增加功能----每次新建文件,都应有不同的默认文件名
步骤:
1、修改主界面的新建触发函数
代码:
void Edit001MainWindow::on_actionNew_triggered()
{
    MyTextEdit *myTextEdit=new MyTextEdit;


    myTextEdit->setMyWindowTitle(); //我们自定义的成员函数(属于MyTextEdit),可以设置自己的标题。
    QMdiSubWindow *mdiSubWindow=mdiArea->addSubWindow(myTextEdit);
    mdiSubWindow->show();
    //myTextEdit->show();
    return;
}


2、在MyTextEdit类中,自定义成员函数
void MyTextEdit::setMyWindowTitle()
{
    QString fileName;
    static int num=1; //注意:这是静态成员变量,走读代码时,这行语句要跳过去,不用读;因为该语句在编译时,已经被执行过了(相当于)。
    fileName=tr("未命名文件%1").arg(num);
    num++; //这行语句,走读代码时,不能跳过。
    setWindowTitle(fileName);
    return;
}
注意:
1、在h文件中,要有函数原型
2、利用静态成员变量,解决了序号连续累加的问题




3.3 增加功能----文件内容一旦被修改,文件标题中应出现*----点击保存后 *应消失
步骤:
1、总体思路是:当MyTextEdit中的document内容被修改时,会触发一个槽函数
2、修改MyTextEdit类的h文件,增加Qt的功能----信号、槽功能
class MyTextEdit : public QTextEdit
{
    Q_OBJECT //新增加的语句,为Qt的1个宏定义,说明该类可以支持信号、槽功能了
public:
    MyTextEdit();
    void loadFile(QString fileName);
    void saveFile(QString fileName);
    void setMyWindowTitle();
public slots:
    void modifyMyWindowTitle();//这2行语句是新增的,即自定义的槽函数modifyMyWindowTitle----当MyTextEdit中的document内容被修改时,会自动执行该槽函数
};
3、修改MyTextEdit类的cpp文件,定义该槽函数
void MyTextEdit::modifyMyWindowTitle()
{
    //setWindowModified(document()->isModified());//与下面语句效果相同
    setWindowModified(true);
    return;
}


4、修改MyTextEdit类的构造函数,连接信号----槽
MyTextEdit::MyTextEdit()
{
    connect(document(),SIGNAL(contentsChanged()),this,SLOT(modifyMyWindowTitle())); //document()函数将返回QTextDocument地址,它就是发送者地址;
} //信号contentsChanged,是系统已有的,代表内容被修改信号
//this是接受者地址,因为后面的自定义槽函数是属于当前类的,因此要填this




5、修改MyTextEdit类的saveFile函数
void MyTextEdit::saveFile(QString fileName)
{
    QFile file(fileName);
    file.open(QFile::WriteOnly|QFile::Text);
    QTextStream out(&file);
    out<<toPlainText();
    fileName+="[*]"; //给QString后加了*,但默认情况下,*号是显示不出来的----这是Qt给我们提供的功能
    setWindowTitle(fileName);//执行该语句,重新设置标题,但如果标题原来有*,则会显示*----需求应该不需要*了
    setWindowModified(false);//这是父类的成员函数,参数为false,表示标题不要显示*----满足了需求
    return;
}


6、修改MyTextEdit类的setMyWindowTitle函数
void MyTextEdit::setMyWindowTitle()
{
    QString fileName;
    static int num=1;
    fileName=tr("未命名文件%1").arg(num)+"[*]";
    //setWindowModified(false);
    num++;
    setWindowTitle(fileName);
    return;
}


7、修改主窗口的actionNew触发函数
void Edit001MainWindow::on_actionNew_triggered()
{
    MyTextEdit *myTextEdit=new MyTextEdit;


    myTextEdit->setMyWindowTitle();
    QMdiSubWindow *mdiSubWindow=mdiArea->addSubWindow(myTextEdit);
    mdiSubWindow->show();
    //myTextEdit->show();
    return;
}




8、修改MyTextEdit类的loadFile函数,标题栏上应能看到文件名(包含路径),而且修改内容后,标题会加*
void MyTextEdit::loadFile(QString fileName)
{


    QFile file(fileName);
    file.open(QFile::ReadOnly|QFile::Text);
    QTextStream in(&file);
    setPlainText(in.readAll());
    fileName+="[*]";
    setWindowTitle(fileName);
    setWindowModified(false);    
    return;
}




3.4  增加功能----退出(但需注意:虽然点击退出了,但如果有文件没有保存,应该提示是否保存、是否取消;如果是取消,则不能退出程序)
思路:利用MyTextEdit类的closeEvent函数,来决定自己的窗口是否关闭;该函数,在关闭自己窗口时被自动触发,是否能真正关闭,可以自己来控制
步骤:
1、在MyTextEdit类的h文件中,声明closeEvent函数
代码:
class MyTextEdit : public QTextEdit
{
    Q_OBJECT
public:
    MyTextEdit();
    void loadFile(QString fileName);
    void saveFile(QString fileName);
    void setMyWindowTitle();
    void closeEvent(QCloseEvent *event); //新增的;父类也有此函数,是虚函数,所以函数原型不能变。这是多态特性的运用。
public slots:
    void modifyMyWindowTitle();
private:
    bool isSaved;
};


2、在MyTextEdit类的cpp文件中,定义closeEvent函数
代码:
void MyTextEdit::closeEvent(QCloseEvent *event)
{
    qDebug()<<"hi,event";
    qDebug()<<isSaved;
    if(!isSaved)
    {
        event->ignore();
        int flag=QMessageBox::warning(this,"告警信息","是否保存当前文件",QMessageBox::Yes|QMessageBox::No|QMessageBox::Cancel);
        if(flag==QMessageBox::Yes)
        {
            QString fileName=QFileDialog::getSaveFileName(this,"保存文件");
            saveFile(fileName);
            event->accept();
        }
        else if(flag==QMessageBox::No)
        {
             event->accept();
        }
        else
        {
            qDebug()<<"click Cancel";
            ;
        }


    }


    return;
}


3、通过主窗口的ui图形界面,在菜单File里增加动作 Exit


4、在主界面的cpp文件里,定义Exit槽函数
void Edit001MainWindow::on_action_Exit_triggered()
{
    mdiArea->closeAllSubWindows(); //虽然意思是关闭所有子窗口,但由于前面重写了closeEvent函数,所以有可能没有全部关闭。
    QMdiSubWindow *mdiSubWindow=mdiArea->currentSubWindow(); //如果没有全部关闭,则该函数不返回NULL
   if(mdiSubWindow==NULL) //如果返回NULL,说明所有窗口都被关闭了,程序可以退出了
        qApp->closeAllWindows(); //执行该语句,程序肯定会退出。
    return;
}








發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章