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;
}








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