QT實現一個 “扯淡Universe” 單機問答系統,構建一個允許用戶分享知識的平臺

學校小學期大作業是用C++寫一個“瞎扯”問答系統,花了幾天時間學了一下QT就開始上手了,雖然做的不是很複雜和完善,但是穩定性經過測試還是不錯,放出來希望能一起交流學習。

1、四個容器,用戶,問題,答案,通知
2、用QT自帶的QSqlite數據庫實現持久化存儲
3、實現登錄註冊,查看,提問,回答,關注,點贊,搜索等基本功能
4、重點是爲了鍛鍊C++的掌握能力,如虛函數、純虛函數,繼承,重載,容器,全局變量


原題如下

程序一:“瞎扯”問答系統(初級版)(60分,抄襲或被抄襲爲0分)
    描述:你需要爲“瞎扯”公司設計一個問答系統,構建一個允許用戶分享知識的平臺。
要求如下:
●   必須用面向對象的方法(繼承+多態)實現問答系統的基本功能。
●   系統中只有用戶這一種角色。
●   用戶可以使用自己的用戶名和密碼登錄系統。
用戶進入系統後可以進行如下操作:
1.  查看操作:用戶可查看當前所有的提問,提問按發表時間排序,順序爲由新到舊,顯示問題列表時至少需顯示用戶和問題標題,用戶選擇一個提問後可以查看該提問的詳細描述及其下的回答,顯示回答列表時至少需要顯示回答用戶、回答內容以及被贊次數。
2.  提問操作:用戶可以在系統中發起提問。
3.  回答操作:用戶可以回答提問。
4.  點贊操作:用戶可以爲回答點贊,被讚的次數要能與回答一同顯示。
5.  添加關注操作:用戶在查看提問和回答時可以選擇添加提問者或回答者爲關注,用戶可以查看自己關注的用戶列表。
6.  註銷操作:即退出登錄,返回最初界面,供後續用戶使用。
●   問題需要有標題和內容兩部分,回答只有內容不需要標題,一個問題可以有多個回答。
●   在列表顯示時應有分頁功能。
●   系統中可能涉及的對象有用戶、問題、回答等。
●   有用戶類,用戶類具有:id、name、password、focuslist等屬性(其他屬性可根據需求自己定義),且具有以下功能。
1.  添加用戶爲關注功能
●   有BasicInfo類,BasicInfo類使用抽象類的方式實現,BasicInfo類具有id、創建者id、創建時間、內容等屬性(其他屬性可根據需求自己定義)
●   BasicInfo類的功能有(定義爲虛函數或純虛函數):
1.  獲取屬性並格式化輸出;
2.  創建問題或答案。
●   BasicInfo子類有問題類和回答類,問題類須有屬性title表示問題的標題,回答類須有屬性praiseNum表示被讚的次數。
注意事項:
●   本題主要考察對C++面向對象特性的掌握,本題需體現繼承、虛函數/純虛函數、抽象類及容器等概念的使用;
●   所有用戶信息,問題信息,答案信息,不強行要求以文本形式存儲,可在程序內部自行定義;
●   不強求關閉程序時存儲程序內數據狀態,即重啓程序後一切可以重置;
●   必須使用容器類作爲保存數據的內部數據結構,可自行選擇合適的容器類;
●   必須使用分離式編譯,各個類實現於自身的.h和.cpp文件中;
●   提供字符操作界面,提供圖形界面的將適當加分。

程序二:“瞎扯”問答系統(高級版)(40分,抄襲或被抄襲爲0分)
描述:在程序一的基礎上添加如下功能:
1.  搜索功能(通過函數重載實現)
1)  按標題搜索功能:用戶可以輸入一個關鍵詞對問題進行搜索,搜索結果爲標題包含該關鍵詞的問題,例如,當搜索“C++”時,顯示的結果爲標題爲“nC++m”的問題,n、m爲任意字符串,n、m可爲空字符串。
2)  按發佈時間搜索功能。
2.  查看關注用戶的提問和回答功能:用戶可以在關注列表中選擇自己關注的用戶,查看該用戶的提問和回答。
■   查看用戶提問列表功能可重載查看所有提問列表功能函數
要求如下:
●   必須在程序一的代碼基礎上修改完成;
●   本題考察對C++面向對象特性的掌握,本題需要體現函數重載、輸入/輸出流重載、文件操作及異常捕獲/處理等概念的使用;
●   採用文本文件或二進制文件來保存所有信息,具體格式可自行定義;
●   爲問題、答案等類信息重載流操作符<<和>>,以便從文件中讀取和寫入信息;
●   必須處理讀文件時的異常;
●   提供字符操作界面,提供圖形界面的將適當加分。

我自己增加的附加功能

附加功能如下:
1.  查看“粉絲”。你可以關注別人,別人自然也能關注你,因此我給用戶類裏新加了一個“followedlist”,因此用戶也能看到自己的粉絲列表,並且可以通過點擊某一項查看用戶信息及提問回答列表。
2.  新增消息類。消息類和問題類回答類一樣繼承自BasicInfo類,消息包括:a.邀請和評論,b.被點贊,c.被關注,d.私信。用戶在首頁可以點擊“通知消息”查看各種通知,並能通過直接點擊通知進入想要頁面。
3.  邀請回答。在用戶查看一個問題時,界面下方會有一個“邀請回答”的按鈕,用戶可以邀請自己關注了的人,也可以邀請自己的“粉絲”,最後也能邀請其他人。被邀請的人會收到通知。
4.  評論回答。在某個回答下面,用戶可以評論當前的這個答案,也可以看到別人發佈的評論。被評論的答案作者會收到一條通知告知某人評論了他的答案。
5.  私信功能。在查看某個用戶的個人資料界面時,右下方有一個“私信”按鈕,可以發一條消息給對方,對方收到私信後雙擊還能直接回復。
6.  搜索答案和用戶。用戶在首頁搜索框中輸入搜索字符點擊搜索後會顯示搜索到的包含所搜字符的問題,答案,用戶。按時間搜索也會顯示滿足要求的答案和問題

我的一點想法

  1. 定義用戶類中 ”focuslist”,”followedlist”,”praiselist”,”answerlist”,”asklist”都是vector容器,保存用戶、答案、問題的ID,之後可以根據ID查找對象。定義問題類中還定義了一個answerlist的容器來保存這個問題下的答案的ID,通過ID獲取到答案。定義答案類的時候則多定義個questionId來保存它對應問題的ID,以便於在查看某一個人的回答時可以看到問題。而新增的通知類由於要滿足四種類型的通知消息,因此只有BasicInfo類中的變量遠遠不夠,應該還得知道發送通知的人,通知的類型問題ID,答案ID,標題等等。
  2. 對於用戶的五個容器僅僅用get,set兩個函數操作是不太夠的,引起各自加了一個處理函數,既能添加成員,又能減少成員。
  3. 由於本次課程設計主要考察容器使用,因此不能依賴數據庫查找,所以程序一啓動就加載了所有數據,放在一個全局變量容器內。
  4. 在顯示問題和答案時,由於要求按時間排序,順序由新到舊,所有在遍歷的時候需要從後往前掃。而又由於要分頁,我實現的方法則是在MainWindow這個類中定義了一個迭代器,初始是指向所有問題的最後一個元素,也就是最新的問題,每顯示一頁迭代器向前移動一定數量。因此實現上一頁,首頁,尾頁功能都只是移動迭代器指向的位置。
  5. 點贊和關注這兩個操作我們應該給它限制只能贊一次或者關注一次,而第二次點擊應該是取消操作所有每次顯示一個答案時都要判斷用戶是否贊過這個答案,是否關注了答主,顯示問題時是否關注題主。
  6. 放棄文件選用數據庫。雖然這次程序設計的目的是爲了鍛鍊C++的使用,但是由於考慮以後數據庫的使用頻率可能會比文件高,所以想自學一些QT操作數據庫的知識。代價也是很大的,花了一天時間才把數據庫方面的函數寫完,由於數據庫的不瞭解,遇到了很多坑。

廢話不多說,直接上代碼,並非完全滿足題目要求,如何我的輸入輸出重載和異常處理解不是很完善。
代碼最後是我的經驗教訓,希望能夠給QT的學習者一些幫助。

完整源碼下載:https://github.com/Kwongrf/CHEDAN_Universe_v2


(0)類的定義聲明
包括用戶類,問題類,回答類,通知類,後三個類繼承於同一個抽象類BasicInfo.
user.h

#ifndef USER_H
#define USER_H


#include <QString>
#include <vector>

using namespace std;

class User
{
public:
    User();

    int getId();
    void setId(int id);
    QString getName();
    void setName(QString name);
    QString getPassword();
    void setPassword(QString password);
    int getPraisedNum();
    void setPraisedNum(int n);
    vector<int> getFocusList();
    void setFocusList(vector<int> focuslist);
    void handleFocusList(int id,bool method);
    vector<int> getFollowedList();
    void setFollowedList(vector<int> followedlist);
    void handleFollowedList(int id,bool method);
    vector<int> getPraiseList();
    void setPraiseList(vector<int> praiselist);
    void handlePraiseList(int id,bool method);

    vector<int> getAnswerList();
    void setAnswerList(vector<int> answerlist);
    void handleAnswerList(int id,bool method);
    vector<int> getAskList();
    void setAskList(vector<int>asklist);
    void handleAskList(int id,bool method);


private:
    int id;
    QString name;
    QString password;
    int praisedNum;
    vector<int> focuslist;//只存放id
    vector<int> followedlist;
    vector<int> praiselist;
    vector<int> answerlist;
    vector<int> asklist;

};

#endif // USER_H

user.cpp

#include "user.h"
#include "global.h"
User::User()
{

}
int User::getId()
{
    return this->id;
}

void User::setId(int id)
{
    this->id = id;
}

QString User::getName()
{
    return this->name;
}

void User::setName(QString name)
{
    this->name = name;
}

QString User::getPassword()
{
    return this->password;
}

void User::setPassword(QString password)
{
    this->password = password;
}
int User::getPraisedNum()
{
    return this->praisedNum;
}

void User::setPraisedNum(int n)
{
    this->praisedNum = n;
}

vector<int> User::getFocusList()
{
    return this->focuslist;
}

void User::handleFocusList(int id,bool method)//method = 1 增加,method = 0減少
{
    if(method)
    {
        this->focuslist.push_back(id);
    }
    else
    {
        for(vector<int>::iterator it=this->focuslist.begin();it!=this->focuslist.end();++it)
        {
            if(*it<0 || *it>Users.size())
                break;
            if(*it ==id)
            {
                it=this->focuslist.erase(it);
                break;
            }
        }
    }
}
void User::setFocusList(vector<int> focuslist)
{
    this->focuslist = focuslist;
}

vector<int> User::getFollowedList()
{
    return this->followedlist;
}

void User::handleFollowedList(int id,bool method)//method = 1 增加,method = 0減少
{
    if(method)
    {
        this->followedlist.push_back(id);
    }
    else
    {
        for(vector<int>::iterator it=this->followedlist.begin();it!=this->followedlist.end();++it)
        {
            if(*it<0 || *it>Users.size())
                break;
            if(*it ==id)
             {
                it=this->followedlist.erase(it);
                break;
            }
        }
    }
}
void User::setFollowedList(vector<int> followedlist)
{
    this->followedlist = followedlist;
}

vector<int> User::getPraiseList()
{
    return this->praiselist;
}

void User::setPraiseList(vector<int> praiselist)
{
    this->praiselist = praiselist;
}

void User::handlePraiseList(int id,bool method)
{
    if(method)
    {
        this->praiselist.push_back(id);
        //this->setPraisedNum(this->getPraisedNum()+1);
        qDebug()<<"pushback success";
    }
    else
    {
        for(vector<int>::iterator it=this->praiselist.begin();it!=this->praiselist.end();it++)
        {

            qDebug()<<"handle "<<*it<<"and id"<<id;
            if(*it ==id)
            {
                it=this->praiselist.erase(it);
                //this->setPraisedNum(this->getPraisedNum()-1);
                qDebug()<<"erase user success";
                break;
            }
            else if(*it > Answers.size()||*it<0)//這裏出現一個錯就是誤以爲it要小於用戶數量,但是肯定不行
                break;
        }
    }
    qDebug()<<"handlePraiseList";
}
vector<int> User::getAnswerList()
{
    return this->answerlist;
}

void User::setAnswerList(vector<int> answerlist)
{
    this->answerlist = answerlist;
}
void User::handleAnswerList(int id,bool method)
{
    if(method)
    {
        this->answerlist.push_back(id);
        qDebug()<<"add answer success";
    }
    else
    {
        for(vector<int>::iterator it=this->answerlist.begin();it!=this->answerlist.end();++it)
        {

            if(*it == id)
            {
                it=this->answerlist.erase(it);
                qDebug()<<"erase answer success";
                break;
            }
            else if(*it> Answers.size()||*it<0)
                break;
        }
    }
}

vector<int> User::getAskList()
{
    return this->asklist;
}

void User::setAskList(vector<int>asklist)
{
    this->asklist = asklist;
}

void User::handleAskList(int id,bool method)
{
    if(method)
    {
        this->asklist.push_back(id);
        qDebug()<<"add ques success";
    }
    else
    {
        for(vector<int>::iterator it=this->asklist.begin();it!=this->asklist.end();++it)
        {

            if(*it ==id)
            {
                it=this->asklist.erase(it);
                qDebug()<<"erase ques success";
                break;
            }
            else if(*it > Questions.size()||*it<0)
                break;
        }
    }
}

basicInfo.h

#ifndef BASICINFO_H
#define BASICINFO_H

#include <QString>



class BasicInfo
{
public:
    BasicInfo();
    int id;
    int userId;
    QString content;
    QString createtime;

    //virtual void show() = 0;
    virtual void created(int id,int userId,QString content,QString createtime) = 0;

    virtual int getId() = 0;
    virtual int getUserId() = 0;
    virtual QString getContent() = 0;
    virtual QString getTime() = 0;
    virtual void setId(int id) = 0;
    virtual void setUserId(int id) = 0;
    virtual void setContent(QString content) = 0;
    virtual void setTime(QString time) = 0;
};

#endif // BASICINFO_H

basic.cpp

#include "basicinfo.h"

BasicInfo::BasicInfo()//因爲是抽象類
{

}

question.h

#ifndef QUESTION_H
#define QUESTION_H
#include "basicinfo.h"
#include <vector>
using namespace std;
class Question :public BasicInfo
{
public:
    Question();


    //void show();
    void created(int id,int userId,QString content,QString createtime);
    int getId();
    int getUserId();
    QString getContent();
    QString getTime();
    vector<int> getAnswerList();
    void setAnswerList(vector<int> answerlist);
    QString getTitle();
    void setTitle(QString title);
    void setId(int id);
    void setUserId(int id);
    void setContent(QString content);
    void setTime(QString time);

    //重載輸出運算符
    friend  ostream  &operator<<(ostream &os,const Question &ques);  //聲明爲友元
    //重載輸入運算符
    friend  istream  &operator>>(istream &is,Question &ques);
private:
    vector<int> answerlist;
     QString title;

};

#endif // QUESTION_H

question.cpp

#include "question.h"
class MainWindow;
Question::Question()
{

}


void Question::created(int id,int userId,QString content,QString createtime)
{
    this->setId(id);
    this->setUserId(userId);
    this->setContent(content);
    this->setTime(createtime);
}

int Question::getId()
{
    return this->id;
}

int Question::getUserId()
{
    return this->userId;
}

QString Question::getContent()
{
    return this->content;
}

QString Question::getTime()
{
    return this->createtime;
}
vector<int> Question::getAnswerList()
{
    return this->answerlist;
}
void Question::setAnswerList(vector<int> answerlist)
{
    this->answerlist = answerlist;
}

QString Question::getTitle()
{
    return this->title;
}
void Question::setTitle(QString title)
{
    this->title = title;
}

void Question::setId(int id)
{
    this->id = id;
}

void Question::setUserId(int id)
{
    this->userId = id;
}

void Question::setContent(QString content)
{
    this->content = content;
}

void Question::setTime(QString createtime)
{
    this->createtime = createtime;
}
ostream  &operator<<(ostream &os,const Question &ques)
{
    //這一步很重要
    QByteArray ba1 = ques.content.toLatin1();
    char *contentstr = ba1.data();
    QByteArray ba2 = ques.createtime.toLatin1();
    char *timestr = ba2.data();
    QByteArray ba3 = ques.title.toLatin1();
    char *titlestr = ba3.data();
    //os<<ans.getId()<<","<<ans.getUserId()<<","<<ans.getQuestionId()<<","<<ans.getPraisedNum()<<","<<ans.getContent()<<","<<ans.getTime();
    os<<ques.id<<ques.userId<<titlestr<<contentstr<<timestr;
    return os;
}

istream  &operator>>(istream &is,Question &ques)
{
    QByteArray ba1 = ques.content.toLatin1();
    char *contentstr = ba1.data();
    QByteArray ba2 = ques.createtime.toLatin1();
    char *timestr = ba2.data();
    QByteArray ba3 = ques.title.toLatin1();
    char *titlestr = ba3.data();
    //is>>ans.getId()>>",">>ans.getUserId()>>",">>ans.getQuestionId()>>",">>ans.getPraisedNum()>>",">>ans.getContent()>>","<<ans.getTime();
    is>>ques.id>>ques.userId>>titlestr>>contentstr>>timestr;
    //輸入判斷
    if(!is)
        ques = Question(); //如果失敗,默認初始化
    return is;
}

notification.h

#ifndef NOTIFICATION_H
#define NOTIFICATION_H
#include "basicinfo.h"

#include <QString>

enum Type{Notice=1,Praise=2,Focused=3,Message=4};

class Notification :public BasicInfo
{
public:
    Notification();


    int getSenderId();
    Type getType();
    QString getTitle();
    int getQuestionId();
    int getAnswerId();
    void created(int id,int userId,QString content,QString createtime);
    int getId();
    int getUserId();

    QString getContent();
    QString getTime();
    void setId(int id);
    void setUserId(int id);

    void setContent(QString content);
    void setTime(QString time);
    void setTitle(QString title);
    void setSenderId(int id);
    void setType(int type);
    void setQuestionId(int id);
    void setAnswerId(int id);

private:

    int senderId;//誰發的
    int questionId;//邀請回答時的情況
    int answerId;//查看評論或點贊時
    QString title;
    Type type;




};

#endif // NOTIFICATION_H

notification.cpp

#include "notification.h"

Notification::Notification()
{

}
int Notification::getId()
{
    return this->id;
}

int Notification::getUserId()
{
    return this->userId;
}

QString Notification::getContent()
{
    return this->content;
}

QString Notification::getTime()
{
    return this->createtime;
}
int Notification::getSenderId()
{
    return this->senderId;
}
QString Notification::getTitle()
{
    return this->title;
}
Type Notification::getType()
{
    return this->type;
}
void Notification::setSenderId(int id)
{
    this->senderId = id;
}
void Notification::setTitle(QString title)
{
    this->title = title;
}
void Notification::setType(int type)
{

        this->type = Type(type);
}

void Notification::setId(int id)
{
    this->id = id;
}

void Notification::setUserId(int id)
{
    this->userId = id;
}

void Notification::setContent(QString content)
{
    this->content = content;
}

void Notification::setTime(QString createtime)
{
    this->createtime = createtime;
}
void Notification::created(int id,int userId,QString content,QString createtime)//因爲沒有實現這個函數導致出現vtable reference
{
    this->setId(id);
    this->setUserId(userId);
    this->setContent(content);
    this->setTime(createtime);
}
int Notification::getQuestionId()
{
    return this->questionId;
}
int Notification::getAnswerId()
{
    return this->answerId;
}
void Notification::setQuestionId(int id)
{
    this->questionId=id;
}
void Notification::setAnswerId(int id)
{
    this->answerId=id;
}

(0.5)全局變量以及數據庫
QT實現全局變量的方法有兩個,一個是 extern ,一個是定義一個類來放所以的全局變量,變量聲明前加static。我這裏用的是使用Global類來放全局函數,用extern來聲明全局變量容器,兩種方法都使用。
database.h

#ifndef DATABASE_H
#define DATABASE_H
#include "user.h"
#include "question.h"
#include "answer.h"
#include "notification.h"
#include <QTextCodec>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QTime>
#include <QSqlError>
#include <QtDebug>
#include <QSqlDriver>
#include <QSqlRecord>
class Database
{
public:
    bool createConnection();                   //創建一個連接
    bool createTable();                    //創建4張數據庫表

    bool insert(User user);                 //插入數據
    bool insert(Question ques);             //出入數據
    bool insert(Answer ans);                //出入數據
    bool insert(Notification notif);

    bool queryById(const int id,User& user);     //查詢用戶信息
    bool queryById(const int id,Question& ques);            //查詢問題信息
    bool queryById(const int id,Answer& ans);            //查詢問題信息

    vector<User> queryAllUser();
    vector<Question> queryAllQues();
    vector<Answer> queryAllAns();
    vector<Answer> queryAllAns(vector<int> ids);
    vector<Notification> queryAllNotif();

    bool update(User user);   //更新
    bool update(Question ques);   //更新
    bool update(Answer ans);   //更新
    //bool deleteById(int id);   //刪除
    //bool sortById();           //排序
};

#endif // DATABASE_H

database.cpp

#include "database.h"
#include "user.h"
#include <QSqlTableModel>
#include <QString>


string vectostr(vector<int>list);
vector<int> split(QString& str,const char* c);

//建立一個數據庫連接
bool Database::createConnection()
{

    //以後就可以用"sqlite1"與數據庫進行連接了
    QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE","sqlite1");
    db.setDatabaseName(".//CHEDAN_Universe.db");
    if( !db.open())
    {   QSqlQuery query(db);
        QSqlError lastError = query.lastError();
        qDebug() << lastError.driverText() << QString(QObject::tr("無法建立數據庫連接"));
        return false;
    }
    qDebug() << QString(QObject::tr("建立數據庫連接"));
    return true;
}
//創建數據庫表
bool Database::createTable()
{

    QSqlDatabase db = QSqlDatabase::database("sqlite1"); //建立數據庫連接
    QSqlQuery query(db);
    bool success1 = query.exec("create table users(id int primary key,name varchar(30),userpassword varchar(30),praisedNum int,answerlist varchar(100),asklist varchar(100),focuslist varchar(100),followedlist varchar(100),praiselist varchar(100))");
    if(success1)
    {
        qDebug() << QObject::tr("數據庫表1創建成功!\n");

    }
    else
    {
        QSqlError lastError = query.lastError();
        qDebug() << lastError.driverText() << QString(QObject::tr("創建數據庫表1失敗"));

    }
    bool success2 = query.exec("create table questions(id int primary key,title varchar(100),userId int,"
                              "content varchar(200),createtime varchar(40),answerlist varchar(100))");
    if(success2)
    {
        qDebug() << QObject::tr("數據庫表2創建成功!\n");

    }
    else
    {
        QSqlError lastError = query.lastError();
        qDebug() << lastError.driverText() << QString(QObject::tr("創建數據庫表2失敗"));

    }
    bool success3 = query.exec("create table answers(id int primary key,userId int,questionId int,"
                              "praisedNum int,content varchar(200),createtime varchar(40))");
    if(success3)
    {
        qDebug() << QObject::tr("數據庫表3創建成功!\n");

    }
    else
    {
        QSqlError lastError = query.lastError();
        qDebug() << lastError.driverText() << QString(QObject::tr("創建數據庫表3失敗"));

    }
    bool success4 = query.exec("create table notifications(id int primary key,userId int,senderId int,noticetype int,"
                              "title varchar(100),content varchar(200),createtime varchar(40),questionId int, answerId int)");
    if(success4)
    {
        qDebug() << QObject::tr("數據庫表4創建成功!\n");

    }
    else
    {
        QSqlError lastError = query.lastError();
        qDebug() << lastError.driverText() << QString(QObject::tr("創建數據庫表4失敗"));
        return false;
    }
    return true;
}

//向數據庫中插入記錄,即註冊賬號信息
bool Database::insert(User user)
{
    QSqlDatabase db = QSqlDatabase::database("sqlite1"); //建立數據庫連接

    QSqlQuery query(db);
    query.prepare("insert into users values(?, ?, ?, ?, ?, ?, ?, ?, ?)");
    query.bindValue(0, user.getId());
    query.bindValue(1, user.getName());
    query.bindValue(2, user.getPassword());
    query.bindValue(3, user.getPraisedNum());
    string answerliststr = vectostr(user.getAnswerList());
    query.bindValue(4,answerliststr.c_str());

    string askliststr = vectostr(user.getAskList());
    query.bindValue(5,askliststr.c_str());
    //將vector<int>轉化成一個字符串存起來
    string focusliststr = vectostr(user.getFocusList());
    query.bindValue(6, focusliststr.c_str());
    //將vector<int>轉化成一個字符串存起來
    string followedliststr = vectostr(user.getFollowedList());
    query.bindValue(7,followedliststr.c_str());

    string praiseliststr = vectostr(user.getPraiseList());
    query.bindValue(8,praiseliststr.c_str());


    bool success=query.exec();
    if(!success)
    {
          QSqlError lastError = query.lastError();
          qDebug() << lastError.driverText() << QString(QObject::tr("插入失敗"));
          return false;
    }
    return true;
}

bool Database::insert(Question ques)
{
    QSqlDatabase db = QSqlDatabase::database("sqlite1"); //建立數據庫連接
    QSqlQuery query(db);
    query.prepare("insert into questions values(?, ?, ?, ?, ?, ?)");
    query.bindValue(0, ques.getId());
    query.bindValue(1, ques.getTitle());
    query.bindValue(2, ques.getUserId());
    query.bindValue(3, ques.getContent());
    query.bindValue(4, ques.getTime());
    //將vector<int>轉化成一個字符串存起來
    string answerliststr = vectostr(ques.getAnswerList());
    query.bindValue(5,answerliststr.c_str());

    bool success=query.exec();
    if(!success)
    {
          QSqlError lastError = query.lastError();
          qDebug() << lastError.driverText() << QString(QObject::tr("插入失敗"));
          return false;
    }
    return true;
}

bool Database::insert(Answer ans)
{
    QSqlDatabase db = QSqlDatabase::database("sqlite1"); //建立數據庫連接
    QSqlQuery query(db);
    query.prepare("insert into answers values(?, ?, ?, ?, ?, ?)");
    query.bindValue(0, ans.getId());
    query.bindValue(1, ans.getUserId());
    query.bindValue(2, ans.getQuestionId());
    query.bindValue(3, ans.getPraisedNum());
    query.bindValue(4, ans.getContent());
    query.bindValue(5, ans.getTime());


    bool success=query.exec();
    if(!success)
    {
          QSqlError lastError = query.lastError();
          qDebug() << lastError.driverText() << QString(QObject::tr("插入失敗"));
          return false;
    }
    return true;
}
bool Database::insert(Notification notif)
{
    QSqlDatabase db = QSqlDatabase::database("sqlite1"); //建立數據庫連接
    QSqlQuery query(db);
    query.prepare("insert into notifications values(?, ?, ?, ?, ?, ?, ?, ?, ?)");
    query.bindValue(0, notif.getId());
    query.bindValue(1, notif.getUserId());
    query.bindValue(2, notif.getSenderId());
    query.bindValue(3, notif.getType());
    query.bindValue(4, notif.getTitle());
    query.bindValue(5, notif.getContent());
    query.bindValue(6, notif.getTime());
    query.bindValue(7, notif.getQuestionId());
    query.bindValue(8, notif.getAnswerId());

    bool success=query.exec();
    if(!success)
    {
          QSqlError lastError = query.lastError();
          qDebug() << lastError.driverText() << QString(QObject::tr("插入失敗"));
          return false;
    }
    return true;
}

//查詢某個用戶信息
bool Database::queryById(const int id,User& user)
{
    QSqlDatabase db = QSqlDatabase::database("sqlite1"); //建立數據庫連接
    /*QSqlTableModel model;
    model.setTable("users");
    model.setEditStrategy(QSqlTableModel::OnManualSubmit);
    char* idstr = itoa(id,idstr,10);
    //model->setFilter(QObject::tr("id = %1").arg(idstr));
    model.setFilter("id = 1");
    if(model.select())
    {
        const char* c = ",";
        QSqlRecord record = model.record(0);
        user.setId(record.value("id").toInt());
        user.setName(record.value("name").toString());
        user.setPassword(record.value("password").toString());
        user.setPraisedNum(record.value("praisedNum").toInt());
        user.setAnswerNum(record.value("answerNum").toInt());
        user.setAskNum(record.value("askNum").toInt());
        QString focusstr = record.value("focuslist").toString();
        vector<int>focuslist = split(focusstr,c);
        user.setFocusList(focuslist);
        QString followedstr = record.value("followedlist").toString();
        user.setFollowedList(split(followedstr,c));
        return true;
    }
    else
    {

        return false;
    }*/
    QSqlQuery query(db);
    bool success = query.exec(QString("select * from users where id = %1").arg(id));
    //bool success = query.exec("select * from users where id = 1");
    qDebug()<< " "<<success;
    if(success)
    {

       if(query.next())
        {
           for(int index = 0; index < 7; index++)
               qDebug() << query.value(index) << " ";
           qDebug() << "\n";
            const char* c = ",";
            user.setId(id);
            user.setName(query.value(1).toString());
            user.setPassword(query.value(2).toString());
            user.setPraisedNum(query.value(3).toInt());
            QString answerstr = query.value(4).toString();
            user.setAnswerList(split(answerstr,c));
            QString askstr = query.value(5).toString();
            user.setAnswerList(split(askstr,c));
            QString focusstr = query.value(6).toString();
            vector<int>focuslist = split(focusstr,c);
            user.setFocusList(focuslist);
            QString followedstr = query.value(7).toString();
            user.setFollowedList(split(followedstr,c));
            QString praisestr = query.value(8).toString();
            user.setPraiseList(split(praisestr,c));


            qDebug()<<query.value(2).toString();
            return true;
        }
        else
           return false;

    }
    else
    {
        qDebug()<<query.lastError();
        return false;
    }
}
bool Database::queryById(const int id,Question& ques)            //查詢問題信息
{
    QSqlDatabase db = QSqlDatabase::database("sqlite1"); //建立數據庫連接
    QSqlQuery query(db);
    bool success = query.exec(QString("select * from questions where id = %1").arg(id));
    qDebug()<< " "<<success;
    if(success)
    {

       if(query.next())
        {
            const char* c = ",";
            ques.setId(id);
            ques.setTitle(query.value(1).toString());
            ques.setUserId(query.value(2).toInt());
            ques.setContent(query.value(3).toString());
            ques.setTime(query.value(4).toString());

            QString answerstr = query.value(5).toString();
            vector<int>answerlist = split(answerstr,c);
            ques.setAnswerList(answerlist);

            return true;
        }
        else
           return false;

    }
    else
    {
        qDebug()<<query.lastError();
        return false;
    }
}

bool Database::queryById(const int id,Answer& ans)            //查詢問題信息
{
    QSqlDatabase db = QSqlDatabase::database("sqlite1"); //建立數據庫連接
    QSqlQuery query(db);
    bool success = query.exec(QString("select * from answers where id = %1").arg(id));
    qDebug()<< " "<<success;
    if(success)
    {

       if(query.next())
        {
            ans.setId(id);
            ans.setUserId(query.value(1).toInt());
            ans.setQuestionId(query.value(2).toInt());
            ans.setPraisedNum(query.value(3).toInt());
            ans.setContent(query.value(4).toString());
            ans.setTime(query.value(5).toString());

            return true;
        }
        else
           return false;

    }
    else
    {
        qDebug()<<query.lastError();
        return false;
    }
}
vector<Question> Database::queryAllQues()                         //返回所有問題
{
    QSqlDatabase db = QSqlDatabase::database("sqlite1"); //建立數據庫連接
    QSqlQuery query(db);
    bool success = query.exec("select * from questions");
    qDebug()<< " "<<success;
    if(success)
    {
        vector<Question> questions;
        while(query.next())
        {
            Question ques;
            const char* c = ",";
            ques.setId(query.value(0).toInt());
            ques.setTitle(query.value(1).toString());
            ques.setUserId(query.value(2).toInt());
            ques.setContent(query.value(3).toString());
            ques.setTime(query.value(4).toString());

            QString answerstr = query.value(5).toString();
            vector<int>answerlist = split(answerstr,c);
            ques.setAnswerList(answerlist);
            questions.push_back(ques);

        }
        return questions;

    }
    else
    {
        qDebug()<<query.lastError();

    }
}
vector<Answer> Database::queryAllAns()
{
    QSqlDatabase db = QSqlDatabase::database("sqlite1"); //建立數據庫連接
    QSqlQuery query(db);
    bool success = query.exec("select * from answers");
    qDebug()<< " "<<success;
    if(success)
    {
        vector<Answer> answers;
        while(query.next())
        {
            Answer ans;
            ans.setId(query.value(0).toInt());
            ans.setUserId(query.value(1).toInt());
            ans.setQuestionId(query.value(2).toInt());
            ans.setPraisedNum(query.value(3).toInt());
            ans.setContent(query.value(4).toString());
            ans.setTime(query.value(5).toString());

            answers.push_back(ans);

        }
        return answers;
    }
}
vector<User> Database::queryAllUser()
{
    QSqlDatabase db = QSqlDatabase::database("sqlite1"); //建立數據庫連接
    QSqlQuery query(db);
    bool success = query.exec("select * from users");
    qDebug()<< " "<<success;
    if(success)
    {
        vector<User> users;
        while(query.next())
        {
            User user;
            const char* c = ",";
            user.setId(query.value(0).toInt());
            user.setName(query.value(1).toString());
            user.setPassword(query.value(2).toString());
            user.setPraisedNum(query.value(3).toInt());
            QString answerstr = query.value(4).toString();
            user.setAnswerList(split(answerstr,c));
            QString askstr = query.value(5).toString();
            user.setAskList(split(askstr,c));
            QString focusstr = query.value(6).toString();
            vector<int>focuslist = split(focusstr,c);
            user.setFocusList(focuslist);
            QString followedstr = query.value(7).toString();
            user.setFollowedList(split(followedstr,c));
            QString praisestr = query.value(8).toString();
            user.setPraiseList(split(praisestr,c));

            users.push_back(user);

        }
        return users;
    }
}

vector<Answer> Database::queryAllAns(vector<int> ids)
{
    Answer ans;
    vector<Answer> answers;
    for (vector<int>::iterator it = ids.begin();it!=ids.end();++it)
    {
        queryById(*it,ans);
        answers.push_back(ans);
    }
    return answers;

}
bool Database::update(User user)   //更新
{
    QSqlDatabase db = QSqlDatabase::database("sqlite1"); //建立數據庫連接
    QSqlQuery query(db);
    query.prepare(QString("update users set id=?,name=?,"
                             "userpassword=?, praisedNum=?,"                           
                             "answerlist=?, asklist=?,"
                             "focuslist=?, followedlist=?,"
                             "praiselist=? where id = %1").arg(user.getId()));

    query.bindValue(0, user.getId());
    query.bindValue(1, user.getName());
    query.bindValue(2, user.getPassword());
    query.bindValue(3, user.getPraisedNum());
    string answerliststr = vectostr(user.getAnswerList());
    query.bindValue(4,answerliststr.c_str());

    string askliststr = vectostr(user.getAskList());
    query.bindValue(5,askliststr.c_str());
    //將vector<int>轉化成一個字符串存起來
    string focusliststr = vectostr(user.getFocusList());
    query.bindValue(6, focusliststr.c_str());
    //將vector<int>轉化成一個字符串存起來
    string followedliststr = vectostr(user.getFollowedList());
    query.bindValue(7,followedliststr.c_str());

    string praiseliststr = vectostr(user.getPraiseList());
    query.bindValue(8,praiseliststr.c_str());

    bool success=query.exec();
    if(!success)
    {
          QSqlError lastError = query.lastError();
          qDebug() << lastError.driverText() << QString(QObject::tr("user更新失敗"));
          return false;
    }
    return true;
}
vector<Notification> Database::queryAllNotif()
{
    QSqlDatabase db = QSqlDatabase::database("sqlite1"); //建立數據庫連接
    QSqlQuery query(db);
    bool success = query.exec("select * from notifications");
    qDebug()<< " "<<success;
    if(success)
    {
        vector<Notification> notifications;
        while(query.next())
        {
            Notification notif;
            notif.setId(query.value(0).toInt());
            notif.setUserId(query.value(1).toInt());
            notif.setSenderId(query.value(2).toInt());
            notif.setType(query.value(3).toInt());
            notif.setTitle(query.value(4).toString());
            notif.setContent(query.value(5).toString());
            notif.setTime(query.value(6).toString());
            notif.setQuestionId(query.value(7).toInt());
            notif.setAnswerId(query.value(8).toInt());
            notifications.push_back(notif);

        }
        return notifications;
    }
}

bool Database::update(Question ques)   //更新
{
    QSqlDatabase db = QSqlDatabase::database("sqlite1"); //建立數據庫連接
    QSqlQuery query(db);
    query.prepare(QString("update questions set id=?,title=?,"
                             "userId=?, content=?,"
                             "createtime=?, answerlist=?"
                             " where id=%1").arg(ques.getId()));
    //qDebug()<<ques.getId()<<" "<<ques.getTitle()<<" "<<ques.getUserId()<<" "<<ques.getContent()<<" "<<ques.getTime();
    query.bindValue(0, ques.getId());
    query.bindValue(1, ques.getTitle());
    query.bindValue(2, ques.getUserId());
    query.bindValue(3, ques.getContent());
    query.bindValue(4, ques.getTime());
    //將vector<int>轉化成一個字符串存起來
    string answerliststr = vectostr(ques.getAnswerList());
    query.bindValue(5,answerliststr.c_str());

    bool success=query.exec();
    if(!success)
    {
          QSqlError lastError = query.lastError();
          qDebug() << lastError.driverText() << QString(QObject::tr("qustion更新失敗"));
          return false;
    }
    return true;
}
bool Database::update(Answer ans)
{
    QSqlDatabase db = QSqlDatabase::database("sqlite1"); //建立數據庫連接
    QSqlQuery query(db);
    query.prepare(QString("update answers set id=?,userId=?,"
                             "questionId=?,praisedNum=?,content=?,"
                             "createtime=? where id=%1").arg(ans.getId()));
    //qDebug()<<ans.getId()<<" "<<ans.getUserId()<<" "<<ans.getPraisedNum()<<" "<<ans.getContent()<<" "<<ans.getTime();
    query.bindValue(0, ans.getId());
    query.bindValue(1, ans.getUserId());
    query.bindValue(2, ans.getQuestionId());
    query.bindValue(3, ans.getPraisedNum());
    query.bindValue(4, ans.getContent());
    query.bindValue(5, ans.getTime());

    bool success=query.exec();
    if(!success)
    {
          QSqlError lastError = query.lastError();
          qDebug() << lastError.driverText() << QString(QObject::tr("answer更新失敗"));
          return false;
    }
    return true;
}


string vectostr(vector<int>list)
{
    string liststr="";
    string str="";
    char* cstr;
    for(vector<int>::iterator it=list.begin();it!=list.end();++it)
    {
        itoa(*it,cstr,10);
        str = cstr;
        liststr =liststr+str;
        if (it!=list.end()-1)
            liststr =liststr+",";
    }
    return liststr;
}

vector<int> split(QString& str,const char* c)
{
    char *cstr, *p;
    vector<int> res;
    //cstr = new char[str.size()+1];
    //strcpy(cstr,str.c_str());
    QByteArray ba = str.toLatin1();
    cstr = ba.data();
    p = strtok(cstr,c);
    //qDebug()<<"split"<<p;
    while(p!=NULL)
    {
        res.push_back(atoi(p));
        p = strtok(NULL,c);
        //qDebug()<<"split"<<p;
    }
    return res;
}

global.h

#ifndef GLOBAL_H
#define GLOBAL_H

#include "database.h"
#include <vector>
using namespace std;


class Global
{
public:
    Global();
    static User getUser(int id);
    static Question getQuestion(int id);
    static Answer getAnswer(int id);
    static Notification getNotification(int id);

    static void update(User user);
    static void update(Question ques);
    static void update(Answer ans);

    static void insert(User user);
    static void insert(Question ques);
    static void insert(Answer ans);
    static void insert(Notification notif);

};

extern Database Db;
extern User USER;
extern vector<Question> Questions;
extern vector<Answer> Answers;
extern vector<User> Users;
extern vector<Notification> Notifications;
#endif // GLOBAL_H

global.cpp

#include "global.h"

/*Global::Global()
{

}*/
Database Db;
User USER;
vector<Question> Questions;
vector<Answer> Answers;
vector<User> Users;
vector<Notification> Notifications;
User Global::getUser(int id)
{
    User user;
    vector<User>::iterator it;
    for(it = Users.begin();it!=Users.end();++it)
    {
        user = *it;
        if(user.getId()==id)
            break;
    }
    if(it!=Users.end())
        return user;
    else
    {
        user.setId(-1);
        return user;
    }
}

Question Global::getQuestion(int id)
{
    Question ques;
    for(vector<Question>::iterator it = Questions.begin();it!=Questions.end();++it)
    {
        ques = *it;
        if(ques.getId()==id)
            break;
    }
    return ques;
}

Answer Global::getAnswer(int id)
{
    Answer ans;
    for(vector<Answer>::iterator it = Answers.begin();it!=Answers.end();++it)
    {
       ans = *it;
        if(ans.getId()==id)
               break;
    }
    return ans;
}
Notification Global::getNotification(int id)
{
    Notification notif;
    for(vector<Notification>::iterator it = Notifications.begin();it!=Notifications.end();++it)
    {
       notif = *it;
        if(notif.getId()==id)
               break;
    }
    return notif;
}

void Global::update(User user)
{
    try{
        for(vector<User>::iterator it = Users.begin();it!=Users.end();++it)
        {

            if((*it).getId()==user.getId())
            {
                (*it).setName(user.getName());
                (*it).setPassword(user.getPassword());
                (*it).setAnswerList(user.getAnswerList());
                (*it).setAskList(user.getAskList());
                (*it).setFollowedList(user.getFollowedList());
                (*it).setPraiseList(user.getPraiseList());
            }
        }
    Db.update(user);
    }
    catch(...)
    {
        qDebug()<<"update user error";
    }
    qDebug()<<"update user success";

}

void Global::update(Question ques)
{
    try{
        for(vector<Question>::iterator it = Questions.begin();it!=Questions.end();++it)
        {

            if((*it).getId()==ques.getId())
            {
                (*it).setTitle(ques.getTitle());
                (*it).setAnswerList(ques.getAnswerList());
                (*it).setContent(ques.getContent());
            }
        }
        Db.update(ques);
    }
    catch(...)
    {
        qDebug()<<"update question error";
    }
}

void Global::update(Answer ans)
{
    for(vector<Answer>::iterator it = Answers.begin();it!=Answers.end();++it)
    {

        if((*it).getId()==ans.getId())
        {

            (*it).setPraisedNum(ans.getPraisedNum());
            (*it).setContent(ans.getContent());
        }
    }
    Db.update(ans);
}

void Global::insert(User user)
{
    Users.push_back(user);
    Db.insert(user);
}

void Global::insert(Question ques)
{
   Questions.push_back(ques);
    Db.insert(ques);
}

void Global::insert(Answer ans)
{
    Answers.push_back(ans);
    Db.insert(ans);
}
void Global::insert(Notification notif)
{
    Notifications.push_back(notif);
    Db.insert(notif);
}

(1)主函數
main.cpp

#include "mainwindow.h"
#include <QApplication>
#include <QLabel>
#include <QMovie>
#include <QSplashScreen>
#include "signin.h"
#include "global.h"
#include <synchapi.h>
int main(int argc, char *argv[])
{

    QApplication a(argc, argv);
    MainWindow w;
    try{
        Db.createConnection();
        Db.createTable();
        Questions = Db.queryAllQues();
        Answers = Db.queryAllAns();
        Users = Db.queryAllUser();
        Notifications = Db.queryAllNotif();
    }
    catch(...)
    {
        qDebug()<<"loading datas error";

    }


    for(vector<Answer>::iterator it= Answers.begin();it!=Answers.end();++it)
    {
        Answer a= *it;
        qDebug()<<a.getId()<<" "<<a.getContent();
    }
    for(vector<Question>::iterator it= Questions.begin();it!=Questions.end();++it)
    {
        Question a= *it;
        qDebug()<<a.getId()<<" "<<a.getContent();
    }
    for(vector<User>::iterator it= Users.begin();it!=Users.end();++it)
    {
        User a= *it;
        qDebug()<<a.getId()<<" "<<a.getName();
    }

    QPixmap pixmap(".//image/1.gif");
    QSplashScreen splash(pixmap);
    splash.setWindowOpacity(0.7);// 設置窗口透明度
    QLabel label(&splash);
    QMovie mv(".//image/1.gif");
    label.setMovie(&mv);
    mv.start();
    splash.show();
    splash.setCursor(Qt::BlankCursor);

    for(int i=0; i<10000; i+=mv.speed())
    {
        QCoreApplication::processEvents();

        Sleep(mv.speed());

    }
    SignIn signInDlg;
    splash.finish(&signInDlg);
    signInDlg.setAutoFillBackground(true);
    QPalette p_signin;
    QPixmap pixmap_signin(".//image/594_492.png");
    p_signin.setBrush(QPalette::Window, QBrush(pixmap_signin));
    signInDlg.setPalette(p_signin);
    if(signInDlg.exec() == QDialog::Accepted)
    {

        w.setAutoFillBackground(true);
        QPalette palette;
        QPixmap pixmap(".//image/bg.jpg");
        palette.setBrush(QPalette::Window, QBrush(pixmap));
        w.setPalette(palette);
        w.show();

        w.showQuestions();
        qDebug()<<"ok";
        return a.exec();
    }
    else     
        return 0;

}

(2)登錄
這裏寫圖片描述
signin.h

#ifndef SIGNIN_H
#define SIGNIN_H

#include <QDialog>

namespace Ui {
class SignIn;
}

class SignIn : public QDialog
{
    Q_OBJECT

public:
    explicit SignIn(QWidget *parent = 0);
    ~SignIn();

private slots:
    void on_signInButton_clicked();

    void on_signUpButton_clicked();

private:
    Ui::SignIn *ui;
};

#endif // SIGNIN_H

signin.cpp

#include "signin.h"
#include "ui_signin.h"
#include "user.h"
#include "global.h"
#include <QMessageBox>
#include "signup.h"
SignIn::SignIn(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::SignIn)
{
    ui->setupUi(this);
    this->resize(594,492);
    this->setFixedSize(594,492);
    ui->lineEdit_2->setEchoMode(QLineEdit::Password);
}

SignIn::~SignIn()
{
    delete ui;
}

void SignIn::on_signInButton_clicked()
{
    User user;
    QString CurrentId = ui->lineEdit->text();
    QString CurrentPassWord = ui->lineEdit_2->text();
    bool* ok = NULL;
    int idInt = CurrentId.toInt(ok,10);
    qDebug()<<"idInt"<<idInt;
    user = Global::getUser(idInt);
    if(user.getId()!=-1)
    {
        if(user.getPassword()==CurrentPassWord)
        {

            accept();
            USER = user;
            qDebug()<<"USER.getId()"<<USER.getId();
            return;
        }
        else
        {
            ui->lineEdit_2->clear();
            QMessageBox fail(QMessageBox::NoIcon, "失敗", "密碼錯誤");
            fail.addButton("確定", QMessageBox::AcceptRole);
            fail.exec();
        }
    }
    else
    {
        ui->lineEdit->clear();
        ui->lineEdit_2->clear();
        QMessageBox fail(QMessageBox::NoIcon, "失敗", "賬戶不存在");
        fail.addButton("確定", QMessageBox::AcceptRole);
        fail.exec();
    }
}

void SignIn::on_signUpButton_clicked()
{
    SignUp signUpDlg;
    signUpDlg.setAutoFillBackground(true);
    QPalette palette;
    QPixmap pixmap(".//image/527_511.png");
    palette.setBrush(QPalette::Window, QBrush(pixmap));
    signUpDlg.setPalette(palette);
    signUpDlg.exec();
}

(3)註冊
這裏寫圖片描述
signup.h

#ifndef SIGNUP_H
#define SIGNUP_H

#include <QDialog>

namespace Ui {
class SignUp;
}

class SignUp : public QDialog
{
    Q_OBJECT

public:
    explicit SignUp(QWidget *parent = 0);
    ~SignUp();

private slots:
    void on_buttonBox_accepted();

    void on_buttonBox_rejected();

private:
    Ui::SignUp *ui;
};

#endif // SIGNUP_H

signup.cpp

#include "signup.h"
#include "ui_signup.h"
#include "global.h"

#include <QMessageBox>
SignUp::SignUp(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::SignUp)
{
    ui->setupUi(this);
    this->resize(527,511);
    ui->lineEdit_2->setEchoMode(QLineEdit::Password);
    ui->lineEdit_3->setEchoMode(QLineEdit::Password);
}

SignUp::~SignUp()
{
    delete ui;
}

void SignUp::on_buttonBox_accepted()
{
    QString id = ui->lineEdit->text();
    QString password = ui->lineEdit_2->text();
    QString cfpassword = ui->lineEdit_3->text();
    QString name = ui->lineEdit_4->text();
    bool* ok = NULL;
    User user=Global::getUser(id.toInt(ok,10));
    if(user.getId()!=-1)
    {
        QMessageBox fail(QMessageBox::NoIcon, "失敗", "該賬號已存在");
        ui->lineEdit->clear();
        fail.addButton("確定", QMessageBox::AcceptRole);
        fail.exec();
    }
    else if(password == cfpassword)
    {
        user.setId(id.toInt());
        user.setPassword(password);
        user.setName(name);
        user.setPraisedNum(0);
        vector<int> ls;
        user.setFocusList(ls);
        user.setFollowedList(ls);
        user.setPraiseList(ls);
        user.setAnswerList(ls);
        user.setAskList(ls);
        Global::insert(user);
        this->close();

    }
    else
    {
        QMessageBox fail(QMessageBox::NoIcon, "失敗", "兩次密碼不一致");
        ui->lineEdit_2->clear();
        ui->lineEdit_3->clear();
        fail.addButton("確定", QMessageBox::AcceptRole);
        fail.exec();
    }
}



void SignUp::on_buttonBox_rejected()
{
    this->close();
}

(3)主窗口
這裏寫圖片描述
mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include "question.h"
#include "global.h"
#include "quesanswindow.h"
#include "ask.h"
#include "userdatawindow.h"
#include <vector>
using namespace std;
namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
    void showQuestions();

private slots:
    void on_askQuesButton_clicked();

    void on_tableWidget_doubleClicked(const QModelIndex &index);

    void on_searchButton_clicked();

    void on_userDataButton_clicked();

    void on_freshButton_clicked();

    void on_signoutButton_clicked();

    void on_focusButton_clicked();

    void on_homepageButton_clicked();

    void on_lastpageButton_clicked();

    void on_nextpageButton_clicked();

    void on_endpageButton_clicked();

    void on_gotopageButton_clicked();

    void on_searchButton_2_clicked();

    void on_followedButton_clicked();

    void on_noticeButton_clicked();

private:
    Ui::MainWindow *ui;
    vector<Question>::reverse_iterator qrit;
    int page;
};

#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "global.h"
#include "question.h"
#include "quesanswindow.h"
#include "ask.h"
#include "userdatawindow.h"
#include "signin.h"
#include "focuswindow.h"
#include "searchresult.h"
#include "noticewindow.h"
#include <QMessageBox>
#include <vector>
using namespace std;

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    this->resize(1140,640);
    this->setFixedSize(1140,640);

    ui->dateEdit->setDate(QDate::currentDate());
}

MainWindow::~MainWindow()
{
    delete ui;
}


void MainWindow::showQuestions()
{
    ui->tableWidget->setRowCount(0);
    ui->tableWidget->setColumnCount(5);
    ui->tableWidget->verticalHeader()->setDefaultSectionSize(40);
    ui->tableWidget->setFont(QFont("微軟雅黑", 10, QFont::Bold ));

    ui->tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
    QStringList header;
    header<<tr("ID")<<tr("問題")<<tr("題主")<<tr("回答數")<<tr("時間");
    ui->tableWidget->setHorizontalHeaderLabels(header);
    ui->tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
    ui->tableWidget->setShowGrid(false);
    ui->tableWidget->horizontalHeader()->setStretchLastSection(true);
    ui->tableWidget->setStyleSheet("background-color:rgba(0,0,0,30)");
    ui->tableWidget->horizontalHeader()->setStyleSheet("QHeaderView::section{background:skyblue;}");
    ui->tableWidget->verticalHeader()->setStyleSheet("QHeaderView::section{background:skyblue;}");
    //ui->tableWidget->show();

    //vector<Question> questions = Db.queryAllQues();
//    int flag=0;
//    int row = 0;
//    for(vector<Question>::reverse_iterator rit = Questions.rbegin();rit!=Questions.rend();++rit)
//    {
//        Question ques = *rit;
//        ui->tableWidget->setRowCount(row+1);
//        ui->tableWidget->setItem(row,0,new QTableWidgetItem(QString::number(ques.getId())));
//        ui->tableWidget->setItem(row,1,new QTableWidgetItem(ques.getTitle()));
//        ui->tableWidget->setItem(row,2,new QTableWidgetItem(Global::getUser(ques.getUserId()).getName()));
//        ui->tableWidget->setItem(row,3,new QTableWidgetItem(QString::number(ques.getAnswerList().size())));
//        ui->tableWidget->setItem(row,4,new QTableWidgetItem(ques.getTime()));

//        //qDebug()<<QString::number(ques.getId())<<" "<<ques.getTitle()<<" "<<ques.getTime()<<" "<<row;
//        row++;
//        flag=1;
//    }

//    for(int row = 0;row < Questions.size();row++)
//    {
//        for(int col = 0;col<5;col++)
//            ui->tableWidget->item(row,col)->setTextColor(QColor(220,220,220));
//    }

//    if(flag==0)
//         ui->tableWidget->setRowCount(0);
//    ui->tableWidget->show();

    //實現分頁
   this->on_homepageButton_clicked();

    int max = Questions.size()/10+1;
    int min = 1;
    //設置QLineEdit只能輸入數字
    QIntValidator* validator = new QIntValidator(min,max,this);
    ui->pageNum->setValidator(validator);

}




void MainWindow::on_askQuesButton_clicked()
{
    Ask askDlg;
    askDlg.setAutoFillBackground(true);
    QPalette palette;
    QPixmap pixmap(".//image/bg3.jpg");
    palette.setBrush(QPalette::Window, QBrush(pixmap));
    askDlg.setPalette(palette);
    if(askDlg.exec() ==  QDialog::Accepted)
    {
        this->showQuestions();
    }
}


void MainWindow::on_tableWidget_doubleClicked(const QModelIndex &index)
{
    bool* ok = NULL;
    int id =ui->tableWidget->item(index.row(),0)->text().toInt(ok,10);

    QuesAnsWindow *quesansWindow = new QuesAnsWindow;

    quesansWindow->show();
    quesansWindow->showQuesAnswers(id);
}

void MainWindow::on_searchButton_clicked()
{
    QString searchStr = ui->searchEdit->text();
    if(searchStr!="")
    {
        SearchResult *sr = new SearchResult;
        sr->search(searchStr);
        sr->exec();
    }
    else
    {
        QMessageBox fail(QMessageBox::NoIcon, "失敗", "請輸入搜索內容");
        fail.addButton("確定", QMessageBox::AcceptRole);
        fail.exec();
    }


}
void MainWindow::on_searchButton_2_clicked()
{
    QDate date = ui->dateEdit->date();
    //QDateTime t = QDateTime::fromString(searchStr,"yyyy-MM-dd");
    SearchResult *sr = new SearchResult;
    sr->search(date);
    sr->exec();
}

void MainWindow::on_userDataButton_clicked()
{
    UserdataWindow userdataWindow;//實際上是Dialog

    USER = Global::getUser(USER.getId());//更新USER
    userdataWindow.setUserId(USER.getId());
    userdataWindow.showAllDatas();
    userdataWindow.exec();
}

void MainWindow::on_freshButton_clicked()
{
    this->showQuestions();
}

void MainWindow::on_signoutButton_clicked()
{
    QMessageBox box (QMessageBox::NoIcon,tr("註銷"),tr("確定註銷?"),QMessageBox::Yes|QMessageBox::No,this);
    box.setIconPixmap(QPixmap(".//image/signout.png"));
    QIcon icon(".//image/out.ico");
    box.setWindowIcon(icon);
    box.setButtonText(QMessageBox::Yes,QString("確定"));
    box.setButtonText(QMessageBox::No,QString("取消"));
    if(box.exec()==QMessageBox::Yes)
    {
        this->hide();
        SignIn signin;
        signin.setAutoFillBackground(true);
        QPalette p_signin;
        QPixmap pixmap_signin(".//image/594_492.png");
        p_signin.setBrush(QPalette::Window, QBrush(pixmap_signin));
        signin.setPalette(p_signin);
        signin.show();

        if(signin.exec()==QDialog::Accepted)
          this->show();
        else
          this->close();
    }
}

void MainWindow::on_focusButton_clicked()
{
     FocusWindow* fw = new FocusWindow;//這裏坑!!
     qDebug()<<"0";

     fw->setAutoFillBackground(true);
     QPalette pallete;
     QPixmap pixmap(".//image/bg7.jpg");
     pallete.setBrush(QPalette::Window, QBrush(pixmap));
     fw->setPalette( pallete);qDebug()<<"21";
     fw->show();qDebug()<<"22";
     fw->showTable(1);qDebug()<<"23";
     qDebug()<<"20";
}

void MainWindow::on_followedButton_clicked()
{
    FocusWindow* fw = new FocusWindow;//這裏坑!!
    qDebug()<<"0";

    fw->setAutoFillBackground(true);
    QPalette pallete;
    QPixmap pixmap(".//image/bg7.jpg");
    pallete.setBrush(QPalette::Window, QBrush(pixmap));
    fw->setPalette( pallete);qDebug()<<"21";
    fw->show();qDebug()<<"22";
    fw->showTable(0);qDebug()<<"23";
    qDebug()<<"20";
}

void MainWindow::on_homepageButton_clicked()
{
    qrit = Questions.rbegin();

    this->on_nextpageButton_clicked();
    page = 1;
    ui->pageNum->setText(QString::number(page));
    qDebug()<<"homepage";
}

void MainWindow::on_lastpageButton_clicked()
{
    if (qrit!=Questions.rend())
        qrit-=10;
    else
    {
        int n = Questions.size()%10;
        qrit-=10+n;
    }

    this->on_nextpageButton_clicked();
    if(page>1)
        page--;
    ui->pageNum->setText(QString::number(page));
    qDebug()<<"lastpage";
}

void MainWindow::on_nextpageButton_clicked()
{
    int row=0;
    while(qrit!=Questions.rend()&&row<10)
    {
        Question ques = *qrit;
        ui->tableWidget->setRowCount(row+1);
        ui->tableWidget->setItem(row,0,new QTableWidgetItem(QString::number(ques.getId())));
        ui->tableWidget->setItem(row,1,new QTableWidgetItem(ques.getTitle()));
        ui->tableWidget->setItem(row,2,new QTableWidgetItem(Global::getUser(ques.getUserId()).getName()));
        ui->tableWidget->setItem(row,3,new QTableWidgetItem(QString::number(ques.getAnswerList().size())));
        ui->tableWidget->setItem(row,4,new QTableWidgetItem(ques.getTime()));
        for(int col = 0;col<5;col++)
            ui->tableWidget->item(row,col)->setTextColor(QColor(220,220,220));
        //qDebug()<<QString::number(ques.getId())<<" "<<ques.getTitle()<<" "<<ques.getTime()<<" "<<row;
        row++;
        qrit++;
    }
    ui->tableWidget->show();
    if(qrit!=Questions.rend())
    {
        page++;
        ui->pageNum->setText(QString::number(page));
        qDebug()<<"nextpage";
    }
}

void MainWindow::on_endpageButton_clicked()
{
    int p = Questions.size()/10;
    qrit = Questions.rbegin();
    qrit+=10*p;
    this->on_nextpageButton_clicked();
    page = p+1;
    ui->pageNum->setText(QString::number(page));
    qDebug()<<"endpage";

}

void MainWindow::on_gotopageButton_clicked()
{
    bool* ok = NULL;
    QString pst = ui->pageNum->text();
    int p = pst.toInt(ok,10);
    qrit = Questions.rbegin();
    qrit+=10*(p-1);
    this->on_nextpageButton_clicked();
    page = p;
    ui->pageNum->setText(QString::number(page));

}



void MainWindow::on_noticeButton_clicked()
{
    NoticeWindow *nw = new NoticeWindow;
    nw->show();
}

(4)提問
這裏寫圖片描述
ask.h

#ifndef ASK_H
#define ASK_H

#include <QDialog>

namespace Ui {
class Ask;
}

class Ask : public QDialog
{
    Q_OBJECT

public:
    explicit Ask(QWidget *parent = 0);
    ~Ask();

private slots:
    void on_buttonBox_accepted();

    void on_buttonBox_rejected();

private:
    Ui::Ask *ui;
};

#endif // ASK_H

ask.cpp

#include "ask.h"
#include "ui_ask.h"
#include "question.h"
#include "global.h"

#include <QMessageBox>
Ask::Ask(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Ask)
{
    ui->setupUi(this);
}

Ask::~Ask()
{
    delete ui;
}

void Ask::on_buttonBox_accepted()
{
    Question ques;

    int id=Questions.size()+1;
    int userId=USER.getId();

    QString currentTitle = ui->lineEdit->text();
    QString currentContent = ui->textEdit->toPlainText();
    if(currentTitle!=""&&currentContent!="")
    {
        //ques.setContent(currentContent);
        QDateTime time = QDateTime::currentDateTime();//獲取系統現在的時間
        QString timestr = time.toString("yyyy-MM-dd hh:mm:ss ddd"); //設置顯示格式
        //ques.setTime(timestr);


        ques.created(id,userId,currentContent,timestr);
        ques.setTitle(currentTitle);

        USER.handleAskList(ques.getId(),1);
        Global::update(USER);
        Global::insert(ques);

        qDebug()<<"ask success";
    }
    else
    {
        QMessageBox fail(QMessageBox::NoIcon, "失敗", "請輸入完整的標題和內容");
        fail.addButton("確定", QMessageBox::AcceptRole);
        fail.exec();
    }
}

void Ask::on_buttonBox_rejected()
{
    this->close();
}

(5)問題與答案窗口
這裏寫圖片描述

quesanswindow.h

#ifndef QUESANSWINDOW_H
#define QUESANSWINDOW_H

#include <QWidget>
#include "question.h"
#include "user.h"
#include "answer.h"
#include <vector>
namespace Ui {
class QuesAnsWindow;
}

class QuesAnsWindow : public QWidget
{
    Q_OBJECT

public:
    explicit QuesAnsWindow(QWidget *parent = 0);
    ~QuesAnsWindow();

    void showQuesAnswers(int id);
    void freshTable();
    void setAsker(User user);
    void setQuestion(Question question);
    void setAnswers(vector<Answer> answers);
    void setAnswerer(User user);
    void setCurAnswer(Answer ans);
    User getAnswerer();
    Answer getCurAnswer();
    vector<Answer> getAnswers();
    User getAsker();
    Question getQuestion();

    void showAnswer(int id);

private slots:
    void on_answerQuesButton_clicked();

    void on_tableWidget_clicked(const QModelIndex &index);

    //void on_praiseButton_toggled(bool checked);

    //void on_focusTZButton_toggled(bool checked);

   // void on_focusDZButton_toggled(bool checked);

    void on_freshButton_clicked();

    //void on_praiseButton_clicked(bool checked);

    void on_praiseButton_clicked();

    void on_focusTZButton_clicked();

    void on_focusDZButton_clicked();

    void on_inviteButton_clicked();

    void on_aboutTZButton_clicked();

    void on_aboutDZButton_clicked();

    void on_commentButton_clicked();

private:
    Ui::QuesAnsWindow *ui;

    User asker;
    User answerer;
    Answer curAnswer;
    Question question;
    vector<Answer> answers;
};

#endif // QUESANSWINDOW_H

quesanswindow.cpp

#include "quesanswindow.h"
#include "ui_quesanswindow.h"
#include "answer.h"
#include "global.h"
#include "invitedialog.h"
#include "userdatawindow.h"
#include "commentdialog.h"
#include <iostream>
#include <QMessageBox>
QuesAnsWindow::QuesAnsWindow(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::QuesAnsWindow)
{
    ui->setupUi(this);
    this->setAutoFillBackground(true);
    QPalette palette;
    QPixmap pixmap(".//image/bg4.jpg");
    palette.setBrush(QPalette::Window, QBrush(pixmap));
    this->setPalette(palette);

    this->resize(800,764);
    this->setFixedSize(800,764);
    ui->tableWidget->setRowCount(0);
    ui->tableWidget->setColumnCount(5);
    ui->tableWidget->verticalHeader()->setDefaultSectionSize(50);
    ui->tableWidget->setFont(QFont("微軟雅黑", 10, QFont::Bold ));
    ui->tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
    QStringList header;
    header<<tr("被贊數")<<tr("答主")<<tr("答案ID")<<tr("答主ID")<<tr("時間");
    ui->tableWidget->setHorizontalHeaderLabels(header);
    ui->tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
    ui->tableWidget->setShowGrid(false);
    ui->tableWidget->horizontalHeader()->setStretchLastSection(true);
    ui->tableWidget->setStyleSheet("background-color:rgba(0,0,0,50)");
    ui->tableWidget->horizontalHeader()->setStyleSheet("QHeaderView::section{background:skyblue;}");
    ui->tableWidget->verticalHeader()->setStyleSheet("QHeaderView::section{background:skyblue;}");
    ui->tableWidget->show();
    ui->textBrowser->setStyleSheet("background-color:rgba(0,0,0,50)");
    ui->textBrowser_2->setStyleSheet("background-color:rgba(0,0,0,50)");
    ui->textEdit->setStyleSheet("background-color:rgba(0,0,0,50)");

    ui->praiseButton->setVisible(false);
    ui->focusDZButton->setVisible(false);
    ui->commentButton->setVisible(false);
    ui->aboutDZButton->setVisible(false);
    ui->textBrowser->setFont(QFont("微軟雅黑", 12, QFont::Light ));
    ui->textBrowser->setTextColor(QColor("white"));
    ui->textBrowser_2->setFont(QFont("微軟雅黑", 12, QFont::Light ));
    ui->textBrowser_2->setTextColor(QColor("white"));
    ui->textEdit->setFont(QFont("微軟雅黑", 12, QFont::Light ));
    ui->textEdit->setTextColor(QColor("white"));
}

QuesAnsWindow::~QuesAnsWindow()
{
    delete ui;
}
void QuesAnsWindow::setAsker(User user)
{
    this->asker = user;
}

void QuesAnsWindow::setQuestion(Question question)
{
    this->question = question;
}

User QuesAnsWindow::getAsker()
{
    return this->asker;
}

Question QuesAnsWindow::getQuestion()
{
    return this->question;
}
void QuesAnsWindow::setAnswers(vector<Answer> answers)
{
    this->answers = answers;
}

vector<Answer> QuesAnsWindow::getAnswers()
{
    return this->answers;
}
void QuesAnsWindow::setAnswerer(User user)
{
    this->answerer = user;
}

void QuesAnsWindow::setCurAnswer(Answer ans)
{
    this->curAnswer = ans;
}

User QuesAnsWindow::getAnswerer()
{
    return this->answerer;
}

Answer QuesAnsWindow::getCurAnswer()
{
    return this->curAnswer;
}

void QuesAnsWindow::showQuesAnswers(int id)
{
    Question ques = Global::getQuestion(id);//問題
    this->setQuestion(ques);

    ui->label_title->setText(ques.getTitle());
    ui->textBrowser_2->setText(ques.getContent());
    ui->label_time->setText(ques.getTime());

    User user = Global::getUser(ques.getUserId());//題主
    this->setAsker(user);
    ui->label_tizhu->setText(user.getName());
    vector<int>ansIds = ques.getAnswerList();
    vector<Answer>answers;
    //所有回答
    for(vector<int>::iterator it = ansIds.begin();it!=ansIds.end();++it)
    {
           Answer ans=Global::getAnswer((*it));
           answers.push_back(ans);

    }
    this->setAnswers(answers);//所有回答
    int flag=0;
    int row = 0;
    for(vector<Answer>::reverse_iterator rit = answers.rbegin();rit!=answers.rend();++rit)
    {
        Answer ans = *rit;
        ui->tableWidget->setRowCount(row+1);
        ui->tableWidget->setItem(row,0,new QTableWidgetItem(QString::number(ans.getPraisedNum())));
        ui->tableWidget->setItem(row,1,new QTableWidgetItem(Global::getUser(ans.getUserId()).getName()));
        ui->tableWidget->setItem(row,2,new QTableWidgetItem(QString::number(ans.getId())));
        ui->tableWidget->setItem(row,3,new QTableWidgetItem(QString::number(ans.getUserId())));
        ui->tableWidget->setItem(row,4,new QTableWidgetItem(ans.getTime()));

        qDebug()<<QString::number(ans.getId())<<" "<<ans.getContent()<<" "<<ans.getTime()<<" "<<row;
        row++;
        flag=1;
    }
    for(int row = 0;row < answers.size();row++)
    {
        for(int col = 0;col<5;col++)
            ui->tableWidget->item(row,col)->setTextColor(QColor(220,220,220));
    }
    if(flag==0)
         ui->tableWidget->setRowCount(0);
    ui->tableWidget->show();
    //檢查是否關注題主
    bool flag1 = true;
    User tmpU = this->getAsker();
    if (tmpU.getId()!=USER.getId())
    {
        ui->focusTZButton->setCheckable(true);
        vector<int> focusls = USER.getFocusList();
        for(vector<int>::iterator it = focusls.begin();it != focusls.end();++it)
        {
            User u = Global::getUser(*it);
            if(u.getId()==-1)
                break;
            if(tmpU.getId()== *it)
            {
                flag1=false;//已經關注了
                ui->focusTZButton->setChecked(true);

                ui->focusTZButton->setText("取消關注");
                qDebug()<<"取消關注";
                break;

            }
        }
        if(flag1)
       {
            ui->focusTZButton->setChecked(false);
            ui->focusTZButton->setText("關注題主");
        }
    }
    else
    {
        ui->focusTZButton->setVisible(false);
        ui->aboutTZButton->setVisible(false);
    }
}
void QuesAnsWindow::freshTable()
{

    vector<Answer>answers = this->getAnswers();
    qDebug()<<"freshTable"<<this->getAnswers().size();
    int flag=0;
    int row = 0;
    for(vector<Answer>::reverse_iterator rit = answers.rbegin();rit!=answers.rend();++rit)
    {
        Answer ans = *rit;

        ui->tableWidget->setRowCount(row+1);
        ui->tableWidget->setItem(row,0,new QTableWidgetItem(QString::number(ans.getPraisedNum())));
        ui->tableWidget->setItem(row,1,new QTableWidgetItem(Global::getUser(ans.getUserId()).getName()));
        ui->tableWidget->setItem(row,2,new QTableWidgetItem(QString::number(ans.getId())));
        ui->tableWidget->setItem(row,3,new QTableWidgetItem(QString::number(ans.getUserId())));
        ui->tableWidget->setItem(row,4,new QTableWidgetItem(ans.getTime()));


        qDebug()<<QString::number(ans.getId())<<" "<<ans.getContent()<<" "<<ans.getTime()<<" "<<row;
        row++;
        flag=1;
    }
    for(int row = 0;row < answers.size();row++)
    {
        for(int col = 0;col<5;col++)
            ui->tableWidget->item(row,col)->setTextColor(QColor(220,220,220));
    }
    if(flag==0)
         ui->tableWidget->setRowCount(0);
    ui->tableWidget->show();

}

void QuesAnsWindow::on_answerQuesButton_clicked()
{
    qDebug()<<"6begin";
    QString currentContent = ui->textEdit->document()->toPlainText();
    if(currentContent!="")
    {
        Answer answer;
        int id=Answers.size()+1;

        //answer.setContent(currentContent);
        int userId=USER.getId();
        QDateTime time = QDateTime::currentDateTime();//獲取系統現在的時間
        QString timestr = time.toString("yyyy-MM-dd hh:mm:ss ddd"); //設置顯示格式
        //answer.setTime(timestr);
        answer.created(id,userId,currentContent,timestr);
        answer.setPraisedNum(0);
        answer.setQuestionId(this->getQuestion().getId());
        qDebug()<<"5";

        vector<int> answerlist = this->getQuestion().getAnswerList();
        answerlist.push_back(answer.getId());

        qDebug()<<"4";

        //this->setQuestion(this->getQuestion().setAnswerList(answerlist));//大坑啊,這個一定要總結錯誤
        Question tmpQ = this->getQuestion();
        tmpQ.setAnswerList(answerlist);
        this->setQuestion(tmpQ);
        qDebug()<<"3";

        vector<Answer> answers = this->getAnswers();
        answers.push_back(answer);
        qDebug()<<"answer"<<this->getAnswers().size();
        this->setAnswers(answers);
        qDebug()<<"answer"<<this->getAnswers().size();

        USER.handleAnswerList(answer.getId(),1);
        qDebug()<<"2";
        try
        {
            std::cout<<answer;
        }
        catch(...)
        {
            qDebug()<<"cout<<answer error";
            Global::insert(answer);
        }
        Global::update(this->getQuestion());
        Global::update(USER);
        this->freshTable();
        ui->textEdit->clear();
    }
    else
    {
        QMessageBox fail(QMessageBox::NoIcon, "失敗", "請輸入搜索內容");
        fail.addButton("確定", QMessageBox::AcceptRole);
        fail.exec();
    }
    qDebug()<<"1end";

}
void QuesAnsWindow::showAnswer(int id)
{
    Answer ans;
    ans = Global::getAnswer(id);

    User ansuser = Global::getUser(ans.getUserId());
    this->setAnswerer(ansuser);
    this->setCurAnswer(ans);
    qDebug()<<"on_tableWidget_clicked"<<this->getCurAnswer().getId()<<this->getCurAnswer().getContent();
    ui->label_dazhu->setText(ansuser.getName());
    ui->label_time->setText(ans.getTime());
    ui->label_prsnum->setText(QString::number(ans.getPraisedNum()));
    ui->textBrowser->setText(ans.getContent());

    if(ansuser.getId()==USER.getId())
    {
       ui->praiseButton->setVisible(false);
       ui->focusDZButton->setVisible(false);
       ui->aboutDZButton->setVisible(false);
       ui->commentButton->setVisible(false);

    }
    else
    {
       ui->praiseButton->setVisible(true);
       ui->focusDZButton->setVisible(true);
       ui->aboutDZButton->setVisible(true);
        ui->commentButton->setVisible(true);
       ui->praiseButton->setCheckable(true);
       ui->focusDZButton->setCheckable(true);

    }
    bool flag1 = true;
    vector<int> praisels = USER.getPraiseList();
    for(vector<int>::iterator it = praisels.begin();it != praisels.end();++it)
    {
        if(*it > Answers.size()||*it<0)
            break;
        Answer tmpA = Global::getAnswer(*it);

        if(tmpA.getId()== this->getCurAnswer().getId())
        {
            flag1=false;//已經贊過了
            ui->praiseButton->setChecked(true);
            ui->praiseButton->setText("取消贊");
            break;
        }

    }
    if(flag1)
    {
        ui->praiseButton->setChecked(false);
        ui->praiseButton->setText("贊");
    }
    //檢查是否已經關注答主
    User tmpU = this->getAnswerer();
    bool flag2 = true;
    vector<int> focusls = USER.getFocusList();
    for(vector<int>::iterator it = focusls.begin();it != focusls.end();++it)
    {
        User u = Global::getUser(*it);
        if(u.getId()==-1)
            break;
        if(tmpU.getId()== *it)
        {
            flag2=false;//已經關注了
            ui->focusDZButton->setChecked(true);
            ui->focusDZButton->setText("取消關注");
            break;

        }
    }
    if(flag2)
    {
        ui->focusDZButton->setChecked(false);
        ui->focusDZButton->setText("關注答主");
    }
    //qDebug()<<"on_tableWidget_clicked";
}

void QuesAnsWindow::on_tableWidget_clicked(const QModelIndex &index)
{
    bool* ok = NULL;
    int id =ui->tableWidget->item(index.row(),2)->text().toInt(ok,10);
    qDebug()<<"on_tableWidget_clicked"<<id;
    showAnswer(id);


}


void QuesAnsWindow::on_freshButton_clicked()
{
    freshTable();
}

//關注某人創建通知
void focusNotice(User user)
{
    //創建通知
    Notification notif;
    int id = Notifications.size()+1;
    int userId =user.getId();
    int senderId = USER.getId();
    int questionId = 0;
    int answerId = 0;
    QDateTime time = QDateTime::currentDateTime();//獲取系統現在的時間
    QString timestr = time.toString("yyyy-MM-dd hh:mm:ss ddd"); //設置顯示格式
    QString title = QString("%1 關注了你").arg(USER.getName());
    QString content = "";
    notif.created(id,userId,content,timestr);
    notif.setQuestionId(questionId);
    notif.setAnswerId(answerId);
    notif.setSenderId(senderId);
    notif.setType(3);
    notif.setTitle(title);

    Global::insert(notif);
}


void QuesAnsWindow::on_praiseButton_clicked()
{
    qDebug()<<"begin";
    User tmpU = this->getAnswerer();
    qDebug()<<"on_praiseButton_clicked()"<<this->getCurAnswer().getId()<<this->getCurAnswer().getContent();
    if(tmpU.getId()!=USER.getId())
    {
        bool flag = true;
        vector<int> praisels = USER.getPraiseList();
        for(vector<int>::iterator it = praisels.begin();it != praisels.end();++it)
        {
            if(*it > Answers.size()|| *it<0)
                break;
            Answer tmpA = Global::getAnswer(*it);
            qDebug()<<"tmpA"<<tmpA.getId()<<" "<<tmpA.getContent();
            qDebug()<<"flag1"<<this->getCurAnswer().getId()<<this->getCurAnswer().getContent();
            if(tmpA.getId()== this->getCurAnswer().getId())
            {
                qDebug()<<"flag2";

                flag=false;//已經贊過了
                ui->praiseButton->setText("取消贊");
                qDebug()<<"flag3";
                break;

            }

            qDebug()<<flag;

        }
        if(flag)
        {
            qDebug()<<"flag5";
            int upn= tmpU.getPraisedNum();
            //this->setAnswerer(this->getAnswerer().setPraisedNum(upn+1));


            tmpU.setPraisedNum(upn+1);
            this->setAnswerer(tmpU);
             qDebug()<<"flag4";
            Global::update(this->getAnswerer());

            int apn=this->getCurAnswer().getPraisedNum();
            //this->setCurAnswer(this->getCurAnswer().setPraisedNum(apn+1));
            qDebug()<<"flag3";
            Answer tmpA = this->getCurAnswer();
            tmpA.setPraisedNum(apn+1);
            this->setCurAnswer(tmpA);
            qDebug()<<"flag2";
            Global::update(this->getCurAnswer());
            ui->label_prsnum->setText(QString::number(apn+1));
            ui->praiseButton->setChecked(true);
            ui->praiseButton->setText("取消贊");
            qDebug()<<"flag1";

            USER.handlePraiseList(this->getCurAnswer().getId(),1);
            Global::update(USER);
            qDebug()<<"flag=true";
            //創建通知
            Notification notif;

            int id = Notifications.size()+1;
            int userId =this->getAnswerer().getId();
            int senderId = USER.getId();
            int questionId = this->getQuestion().getId();
            int answerId = this->getCurAnswer().getId();
            QDateTime time = QDateTime::currentDateTime();//獲取系統現在的時間
            QString timestr = time.toString("yyyy-MM-dd hh:mm:ss ddd"); //設置顯示格式
            QString title = QString("%1 讚了你的回答").arg(USER.getName());
            QString content = this->getCurAnswer().getContent();
            notif.created(id,userId,content,timestr);
            notif.setQuestionId(questionId);
            notif.setAnswerId(answerId);
            notif.setSenderId(senderId);
            notif.setType(2);
            notif.setTitle(title);

            Global::insert(notif);
        }
        else
        {   qDebug()<<"f4";
            int upn=tmpU.getPraisedNum();
            //this->setAnswerer(this->getAnswerer().setPraisedNum(upn+1));


            tmpU.setPraisedNum(upn-1);
            this->setAnswerer(tmpU);
            qDebug()<<"f3";
            Global::update(this->getAnswerer());
            int apn=(this->getCurAnswer()).getPraisedNum();
            //this->setCurAnswer(this->getCurAnswer().setPraisedNum(apn+1));
            qDebug()<<"f2";
            Answer tmpA = this->getCurAnswer();
            tmpA.setPraisedNum(apn-1);
            this->setCurAnswer(tmpA);
            qDebug()<<"f1";
            Global::update(this->getCurAnswer());
            ui->label_prsnum->setText(QString::number(apn-1));
            qDebug()<<"f0";
            ui->praiseButton->setChecked(false);
            ui->praiseButton->setText("贊");
            USER.handlePraiseList(this->getCurAnswer().getId(),0);qDebug()<<this->getCurAnswer().getId()<<" "<<this->getCurAnswer().getPraisedNum();
            Global::update(USER);qDebug()<<USER.getPraisedNum();
            qDebug()<<"flag=false";
        }
    }
}

void QuesAnsWindow::on_focusTZButton_clicked()
{
    User tmpU = this->getAsker();
    if(tmpU.getId()!=USER.getId())
    {
        bool flag = true;
        vector<int> focusls=USER.getFocusList();//這又是一個大大的坑!!!!這是爲什麼呢????
        for(vector<int>::iterator it= focusls.begin(); it != focusls.end(); ++it)
        {
            User u = Global::getUser(*it);
             qDebug()<<"onfocusTZbt"<<u.getId()<<u.getName()<<" "<<tmpU.getId()<<" "<<*it;
            if(u.getId()==-1)
                break;
            if(tmpU.getId()== *it)
            {
                flag=false;//已經關注了

                break;
            }
        }
        if(flag)
        {

            tmpU.handleFollowedList(USER.getId(),1);
            this->setAsker(tmpU);

            USER.handleFocusList(this->getAsker().getId(),1);
            Global::update(this->getAsker());
            Global::update(USER);
            focusNotice(this->getAsker());
            ui->focusTZButton->setChecked(true);
            ui->focusTZButton->setText("取消關注");
            qDebug()<<"取消關注"<<USER.getFocusList().size()<<USER.getFollowedList().size();
        }
        else
        {

            tmpU.handleFollowedList(USER.getId(),0);
            qDebug()<<"flag=false"<<this->getAsker().getId()<<" "<<tmpU.getId();
            this->setAsker(tmpU);
            qDebug()<<"flag=false"<<this->getAsker().getId();
            //this->getAsker().handleFollowedList(USER.getId(),0);
            USER.handleFocusList(this->getAsker().getId(),0);
            qDebug()<<"USER.handleFocusList"<<this->getAsker().getId();
            Global::update(this->getAsker());
            Global::update(USER);
            ui->focusTZButton->setChecked(false);
            ui->focusTZButton->setText("關注題主");
            qDebug()<<"關注題主"<<USER.getFocusList().size()<<USER.getFollowedList().size();
        }
    }
}

void QuesAnsWindow::on_focusDZButton_clicked()
{
    User tmpU = this->getAnswerer();
    if( tmpU.getId()!=USER.getId())
    {
        bool flag = true;
        vector<int> focusls = USER.getFocusList();
        for(vector<int>::iterator it = focusls.begin();it != focusls.end();++it)
        {
            User u = Global::getUser(*it);
            qDebug()<<"onfocusDZbt"<<u.getId()<<u.getName()<<" "<<tmpU.getId()<<" "<<*it;;
            if(u.getId()==-1)
                break;
            if(tmpU.getId()== *it)
            {
                flag=false;//已經關注了

                break;
            }
        }
        if(flag)
        {

            tmpU.handleFollowedList(USER.getId(),1);
            this->setAnswerer(tmpU);
            //this->getAnswerer().handleFollowedList(USER.getId(),1);

            USER.handleFocusList(this->getAnswerer().getId(),1);
            Global::update(this->getAnswerer());
            Global::update(USER);
            focusNotice(this->getAnswerer());
            ui->focusDZButton->setChecked(true);
            ui->focusDZButton->setText("取消關注");
            qDebug()<<"取消關注"<<USER.getFocusList().size()<<USER.getFollowedList().size();
        }
        else
        {

            tmpU.handleFollowedList(USER.getId(),0);
            this->setAnswerer(tmpU);
            //this->getAnswerer().handleFollowedList(USER.getId(),0);
            USER.handleFocusList(this->getAnswerer().getId(),0);
            Global::update(this->getAnswerer());
            Global::update(USER);
            ui->focusDZButton->setChecked(false);
            ui->focusDZButton->setText("關注答主");
            qDebug()<<"關注答主"<<USER.getFocusList().size()<<USER.getFollowedList().size();
        }
    }

}

void QuesAnsWindow::on_inviteButton_clicked()
{
    InviteDialog *ivtdlg = new InviteDialog;
    ivtdlg->setQuestionId(this->getQuestion().getId());
    ivtdlg->exec();
}


void QuesAnsWindow::on_aboutTZButton_clicked()
{
    UserdataWindow *uw = new UserdataWindow;
    uw->setUserId(this->getAsker().getId());
    uw->show();
    uw->showAllDatas();
    this->hide();
}

void QuesAnsWindow::on_aboutDZButton_clicked()
{
    UserdataWindow *uw = new UserdataWindow;
    uw->setUserId(this->getAnswerer().getId());
    uw->show();
    uw->showAllDatas();
    this->hide();
}

void QuesAnsWindow::on_commentButton_clicked()
{
    CommentDialog *cmtDlg = new CommentDialog; 
    cmtDlg->setAnswerId(this->getCurAnswer().getId());
    cmtDlg->setAnswererId(this->getAnswerer().getId());
    cmtDlg->showComments();
    cmtDlg->exec();

}

(6)個人中心頁面
這裏寫圖片描述

userdatawindow.h

#ifndef USERDATAWINDOW_H
#define USERDATAWINDOW_H

#include "user.h"
#include <QDialog>

namespace Ui {
class UserdataWindow;
}

class UserdataWindow : public QDialog
{
    Q_OBJECT

public:
    explicit UserdataWindow(QWidget *parent = 0);
    ~UserdataWindow();
    void showAllDatas();
    void showUserDatas();
    void showQuestions();
    void showAnswers();
    int getUserId();
    void setUserId(int id);

private slots:
    void on_changePassButton_clicked();

    void on_changeNameButton_clicked();


    void on_tableWidget_doubleClicked(const QModelIndex &index);

    void on_tableWidget_2_doubleClicked(const QModelIndex &index);


    void on_messageButton_clicked();

private:
    Ui::UserdataWindow *ui;
    int userId;
};

#endif // USERDATAWINDOW_H

userdatawindow.cpp

#ifndef USERDATAWINDOW_H
#define USERDATAWINDOW_H

#include "user.h"
#include <QDialog>

namespace Ui {
class UserdataWindow;
}

class UserdataWindow : public QDialog
{
    Q_OBJECT

public:
    explicit UserdataWindow(QWidget *parent = 0);
    ~UserdataWindow();
    void showAllDatas();
    void showUserDatas();
    void showQuestions();
    void showAnswers();
    int getUserId();
    void setUserId(int id);

private slots:
    void on_changePassButton_clicked();

    void on_changeNameButton_clicked();


    void on_tableWidget_doubleClicked(const QModelIndex &index);

    void on_tableWidget_2_doubleClicked(const QModelIndex &index);


    void on_messageButton_clicked();

private:
    Ui::UserdataWindow *ui;
    int userId;
};

#endif // USERDATAWINDOW_H

(7)關注列表(粉絲列表)
這裏寫圖片描述

focuswindow.h

#ifndef FOCUSWINDOW_H
#define FOCUSWINDOW_H

#include <QWidget>

namespace Ui {
class FocusWindow;
}

class FocusWindow : public QWidget
{
    Q_OBJECT

public:
    explicit FocusWindow(QWidget *parent = 0);
    void showTable(bool type);
    ~FocusWindow();


public slots:
    void onBtnClicked(void);

private slots:
    void on_tableWidget_doubleClicked(const QModelIndex &index);

private:
    Ui::FocusWindow *ui;
};

#endif // FOCUSWINDOW_H

focuswindow.cpp

#include "focuswindow.h"
#include "ui_focuswindow.h"
#include "global.h"
#include "userdatawindow.h"

#include <QPushButton>
FocusWindow::FocusWindow(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::FocusWindow)
{
    ui->setupUi(this);
    this->resize(1024,576);
    this->setFixedSize(1024,576);
    qDebug()<<"1";
    ui->tableWidget->setRowCount(0);
    ui->tableWidget->setColumnCount(8);
    ui->tableWidget->verticalHeader()->setDefaultSectionSize(50);
    ui->tableWidget->setFont(QFont("微軟雅黑", 10, QFont::Bold ));
    ui->tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
    QStringList header;
    header<<tr("ID")<<tr("用戶名")<<tr("回答數")<<tr("提問數")<<tr("獲贊數")<<tr("關注數")<<tr("粉絲數")<<tr("操作");
    ui->tableWidget->setHorizontalHeaderLabels(header);
    ui->tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
    ui->tableWidget->setShowGrid(false);
    ui->tableWidget->horizontalHeader()->setStretchLastSection(true);
    ui->tableWidget->setStyleSheet("background-color:rgba(0,0,0,30)");
    ui->tableWidget->horizontalHeader()->setStyleSheet("QHeaderView::section{background:skyblue;}");
    ui->tableWidget->verticalHeader()->setStyleSheet("QHeaderView::section{background:skyblue;}");
    ui->tableWidget->show();
    qDebug()<<"2";
    //vector<Question> questions = Db.queryAllQues();

}

FocusWindow::~FocusWindow()
{
    delete ui;
}
void FocusWindow::showTable(bool type)
{
    if(type)//查看我的關注
    {
        ui->label->setText("我的關注列表");
        int flag=0;
        int row = 0;
        qDebug()<<"24";
        for(int i = USER.getFocusList().size()-1;i>=0;i--)
        {
            int id = USER.getFocusList().at(i);
            User u = Global::getUser(id);
            if(u.getId()==-1)
                break;
            ui->tableWidget->setRowCount(row+1);
            ui->tableWidget->setItem(row,0,new QTableWidgetItem(QString::number(u.getId())));
            ui->tableWidget->setItem(row,1,new QTableWidgetItem(u.getName()));
            ui->tableWidget->setItem(row,2,new QTableWidgetItem(QString::number(u.getAnswerList().size())));
            ui->tableWidget->setItem(row,3,new QTableWidgetItem(QString::number(u.getAskList().size())));
            ui->tableWidget->setItem(row,4,new QTableWidgetItem(QString::number(u.getPraisedNum())));
            ui->tableWidget->setItem(row,5,new QTableWidgetItem(QString::number(u.getFocusList().size())));
            ui->tableWidget->setItem(row,6,new QTableWidgetItem(QString::number(u.getFollowedList().size())));
            QPushButton * pBtn = new QPushButton();
            pBtn->setText("取消關注");
            pBtn->setStyleSheet("color:rgb(255,255,255)");
            connect(pBtn, SIGNAL(clicked()), this, SLOT(onBtnClicked()));
            ui->tableWidget->setCellWidget(row,7,pBtn);
            qDebug()<<QString::number(u.getId())<<" "<<u.getName()<<row<<" "<<i<<" "<<USER.getFocusList().size();
            row++;
            flag=1;
        }
        for(int row = 0;row < USER.getFocusList().size();row++)
        {
            for(int col = 0;col<7;col++)
                ui->tableWidget->item(row,col)->setTextColor(QColor(220,220,220));
        }
        if(flag==0)
             ui->tableWidget->setRowCount(0);
        ui->tableWidget->show();
         qDebug()<<"3";
    }
    else
    {
        ui->label->setText("我的粉絲列表");
        int flag=0;
        int row = 0;
        qDebug()<<"24";
        for(int i = USER.getFollowedList().size()-1;i>=0;i--)
        {
            int id = USER.getFollowedList().at(i);
            User u = Global::getUser(id);
            if(u.getId()==-1)
                break;
            ui->tableWidget->setRowCount(row+1);
            ui->tableWidget->setItem(row,0,new QTableWidgetItem(QString::number(u.getId())));
            ui->tableWidget->setItem(row,1,new QTableWidgetItem(u.getName()));
            ui->tableWidget->setItem(row,2,new QTableWidgetItem(QString::number(u.getAnswerList().size())));
            ui->tableWidget->setItem(row,3,new QTableWidgetItem(QString::number(u.getAskList().size())));
            ui->tableWidget->setItem(row,4,new QTableWidgetItem(QString::number(u.getPraisedNum())));
            ui->tableWidget->setItem(row,5,new QTableWidgetItem(QString::number(u.getFocusList().size())));
            ui->tableWidget->setItem(row,6,new QTableWidgetItem(QString::number(u.getFollowedList().size())));

            qDebug()<<QString::number(u.getId())<<" "<<u.getName()<<row<<" "<<i<<" "<<USER.getFocusList().size();
            row++;
            flag=1;
        }
        for(int row = 0;row < USER.getFollowedList().size();row++)
        {
            for(int col = 0;col<7;col++)
                ui->tableWidget->item(row,col)->setTextColor(QColor(220,220,220));
        }
        if(flag==0)
             ui->tableWidget->setRowCount(0);
        ui->tableWidget->show();
         qDebug()<<"3";
    }

}
void FocusWindow::onBtnClicked(void)
{
    QPushButton * senderObj=qobject_cast<QPushButton *>(sender());
    if(senderObj == 0)
    {
        return;
    }
    QModelIndex index =ui->tableWidget->indexAt(QPoint(senderObj->frameGeometry().x(),senderObj->frameGeometry().y()));
    int row=index.row();
    qDebug()<<"row:"<<row;
    bool* ok = NULL;
    int id =ui->tableWidget->item(index.row(),0)->text().toInt(ok,10);
    User user = Global::getUser(id);
    USER.handleFocusList(id,0);
    user.handleFollowedList(USER.getId(),0);
    Global::update(USER);
    Global::update(user);
    qDebug()<<"取消關注成功";
    this->showTable(1);
}

void FocusWindow::on_tableWidget_doubleClicked(const QModelIndex &index)
{
    bool* ok = NULL;
    int id =ui->tableWidget->item(index.row(),0)->text().toInt(ok,10);

    UserdataWindow *uw = new UserdataWindow;
    uw->setUserId(id);
    uw->show();
    uw->showAllDatas();
    this->close();
}

(8)搜索結果
這裏寫圖片描述

searchresult.h

#ifndef SEARCHRESULT_H
#define SEARCHRESULT_H

#include <QDialog>
#include "question.h"
#include "answer.h"
#include "user.h"
namespace Ui {
class SearchResult;
}

class SearchResult : public QDialog
{
    Q_OBJECT

public:
    explicit SearchResult(QWidget *parent = 0);
    ~SearchResult();
    bool search(QString str);
    bool search(Question q);
    bool search(Answer a);
    bool search(User u);
    bool search(QDate d);

private:
    Ui::SearchResult *ui;
};

#endif // SEARCHRESULT_H

searchresult.cpp

#include "searchresult.h"
#include "ui_searchresult.h"
#include "global.h"

SearchResult::SearchResult(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::SearchResult)
{
    ui->setupUi(this);

    this->resize(1024,576);
    this->setFixedSize(1024,576);
    this->setAutoFillBackground(true);
    QPalette palette;
    QPixmap pixmap(".//image/bg7.jpg");
    palette.setBrush(QPalette::Window, QBrush(pixmap));
    this->setPalette(palette);

    qDebug()<<"1";
    ui->tableWidget->setRowCount(0);
    ui->tableWidget->setColumnCount(5);
    ui->tableWidget->verticalHeader()->setDefaultSectionSize(30);
    ui->tableWidget->setFont(QFont("微軟雅黑", 10, QFont::Bold ));
    ui->tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
    QStringList header;
    header<<tr("ID")<<tr("問題")<<tr("回答數")<<tr("題主")<<tr("時間");
    ui->tableWidget->setHorizontalHeaderLabels(header);
    ui->tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
    ui->tableWidget->setShowGrid(false);
    ui->tableWidget->horizontalHeader()->setStretchLastSection(true);
    ui->tableWidget->setStyleSheet("background-color:rgba(0,0,0,30)");
    ui->tableWidget->horizontalHeader()->setStyleSheet("QHeaderView::section{background:skyblue;}");
    ui->tableWidget->verticalHeader()->setStyleSheet("QHeaderView::section{background:skyblue;}");

    ui->tableWidget_2->setRowCount(0);
    ui->tableWidget_2->setColumnCount(6);
    ui->tableWidget_2->verticalHeader()->setDefaultSectionSize(30);
    ui->tableWidget_2->setFont(QFont("微軟雅黑", 10, QFont::Bold ));
    ui->tableWidget_2->setEditTriggers(QAbstractItemView::NoEditTriggers);
    QStringList header2;
    header2<<tr("ID")<<tr("回答")<<tr("問題")<<tr("獲贊數")<<tr("答主")<<tr("時間");;
    ui->tableWidget_2->setHorizontalHeaderLabels(header2);
    ui->tableWidget_2->setSelectionBehavior(QAbstractItemView::SelectRows);
    ui->tableWidget_2->setShowGrid(false);
    ui->tableWidget_2->horizontalHeader()->setStretchLastSection(true);
    ui->tableWidget_2->setStyleSheet("background-color:rgba(0,0,0,30)");
    ui->tableWidget_2->horizontalHeader()->setStyleSheet("QHeaderView::section{background:skyblue;}");
    ui->tableWidget_2->verticalHeader()->setStyleSheet("QHeaderView::section{background:skyblue;}");

    ui->tableWidget_3->setRowCount(0);
    ui->tableWidget_3->setColumnCount(5);
    ui->tableWidget_3->verticalHeader()->setDefaultSectionSize(50);
    ui->tableWidget_3->setFont(QFont("微軟雅黑", 10, QFont::Bold ));
    ui->tableWidget_3->setEditTriggers(QAbstractItemView::NoEditTriggers);
    QStringList header3;
    header3<<tr("ID")<<tr("用戶名")<<tr("回答數")<<tr("提問數")<<tr("獲贊數");
    ui->tableWidget_3->setHorizontalHeaderLabels(header3);
    ui->tableWidget_3->setSelectionBehavior(QAbstractItemView::SelectRows);
    ui->tableWidget_3->setShowGrid(false);
    ui->tableWidget_3->horizontalHeader()->setStretchLastSection(true);
    ui->tableWidget_3->setStyleSheet("background-color:rgba(0,0,0,30)");
    ui->tableWidget_3->horizontalHeader()->setStyleSheet("QHeaderView::section{background:skyblue;}");
    ui->tableWidget_3->verticalHeader()->setStyleSheet("QHeaderView::section{background:skyblue;}");
}

SearchResult::~SearchResult()
{
    delete ui;
}

bool SearchResult::search(QString str)
{
    Question q;
    q.setTitle(str);
    this->search(q);
    qDebug()<<"search question";
    Answer a;
    a.setContent(str);
    this->search(a);
    qDebug()<<"search answer";
    User u;
    u.setName(str);
    this->search(u);
    qDebug()<<"search user";

}

bool SearchResult::search(Question q)
{
    int row=0;
    for(vector<Question>::iterator it = Questions.begin(); it!=Questions.end(); ++it)
    {
        Question que=*it;
        if(que.getTitle().contains(q.getTitle()))
        {
            ui->tableWidget->setRowCount(row+1);
            ui->tableWidget->setItem(row,0,new QTableWidgetItem(QString::number(que.getId())));
            ui->tableWidget->setItem(row,1,new QTableWidgetItem(que.getTitle()));
            ui->tableWidget->setItem(row,2,new QTableWidgetItem(QString::number(que.getAnswerList().size())));
            ui->tableWidget->setItem(row,3,new QTableWidgetItem(Global::getUser(que.getUserId()).getName()));
            ui->tableWidget->setItem(row,4,new QTableWidgetItem(que.getTime()));
            for(int col = 0;col<ui->tableWidget->columnCount();col++)
                ui->tableWidget->item(row,col)->setTextColor(QColor(220,220,220));
            row++;

        }
    }
    if(row == 0)
        ui->tableWidget->setItem(0,0,new QTableWidgetItem(QString("未找到相關問題")));
}

bool SearchResult::search(Answer a)
{
    int row=0;
    for(vector<Answer>::iterator it = Answers.begin(); it!=Answers.end(); ++it)
    {
        Answer ans=*it;
        if(ans.getContent().contains(a.getContent()))
        {
            ui->tableWidget_2->setRowCount(row+1);
            ui->tableWidget_2->setItem(row,0,new QTableWidgetItem(QString::number(ans.getId())));
            ui->tableWidget_2->setItem(row,1,new QTableWidgetItem(ans.getContent()));
            ui->tableWidget_2->setItem(row,2,new QTableWidgetItem(Global::getQuestion(ans.getQuestionId()).getTitle()));
            ui->tableWidget_2->setItem(row,3,new QTableWidgetItem(QString::number(ans.getPraisedNum())));
            ui->tableWidget_2->setItem(row,4,new QTableWidgetItem(Global::getUser(ans.getUserId()).getName()));
            ui->tableWidget_2->setItem(row,5,new QTableWidgetItem(ans.getTime()));
            for(int col = 0;col<ui->tableWidget_2->columnCount();col++)
                ui->tableWidget_2->item(row,col)->setTextColor(QColor(220,220,220));
            row++;
        }
    }
    if(row == 0)
        ui->tableWidget_2->setItem(0,0,new QTableWidgetItem(QString("未找到相關回答")));
}

bool SearchResult::search(User u)
{
    int row=0;
    for(vector<User>::iterator it = Users.begin(); it!=Users.end(); ++it)
    {
        User user=*it;
        if(user.getName().contains(u.getName()))
        {
            ui->tableWidget_3->setRowCount(row+1);
            ui->tableWidget_3->setItem(row,0,new QTableWidgetItem(QString::number(user.getId())));
            ui->tableWidget_3->setItem(row,1,new QTableWidgetItem(user.getName()));
            ui->tableWidget_3->setItem(row,2,new QTableWidgetItem(user.getAnswerList().size()));
            ui->tableWidget_3->setItem(row,3,new QTableWidgetItem(user.getAskList().size()));
            ui->tableWidget_3->setItem(row,4,new QTableWidgetItem(user.getPraisedNum()));
            for(int col = 0;col<ui->tableWidget_3->columnCount();col++)
                ui->tableWidget_3->item(row,col)->setTextColor(QColor(220,220,220));
            row++;
        }
    }
    if(row == 0)
        ui->tableWidget_3->setItem(0,0,new QTableWidgetItem(QString("未找到相關用戶")));
}

bool SearchResult::search(QDate d)
{
    qDebug()<<"search question by time";
    QString timestr = d.toString("yyyy-MM-dd");
    ui->tableWidget_3->setVisible(false);
    ui->label_3->setVisible(false);
    this->resize(720,612);
    int row1=0;
    for(vector<Question>::iterator it = Questions.begin(); it!=Questions.end(); ++it)
    {
        Question que=*it;
        if(que.getTime().contains(timestr))
        {
            ui->tableWidget->setRowCount(row1+1);
            ui->tableWidget->setItem(row1,0,new QTableWidgetItem(QString::number(que.getId())));
            ui->tableWidget->setItem(row1,1,new QTableWidgetItem(que.getTitle()));
            ui->tableWidget->setItem(row1,2,new QTableWidgetItem(QString::number(que.getAnswerList().size())));
            ui->tableWidget->setItem(row1,3,new QTableWidgetItem(Global::getUser(que.getUserId()).getName()));
            ui->tableWidget->setItem(row1,4,new QTableWidgetItem(que.getTime()));
            for(int col = 0;col<ui->tableWidget->columnCount();col++)
                ui->tableWidget->item(row1,col)->setTextColor(QColor(220,220,220));
            row1++;

        }
    }
    if(row1 == 0)
        ui->tableWidget->setItem(0,0,new QTableWidgetItem(QString("未找到相關問題")));
    qDebug()<<"search answer by time";
    int row=0;
    for(vector<Answer>::iterator it = Answers.begin(); it!=Answers.end(); ++it)
    {
        Answer ans=*it;
        if(ans.getTime().contains(timestr))
        {
            ui->tableWidget_2->setRowCount(row+1);
            ui->tableWidget_2->setItem(row,0,new QTableWidgetItem(QString::number(ans.getId())));
            ui->tableWidget_2->setItem(row,1,new QTableWidgetItem(ans.getContent()));
            ui->tableWidget_2->setItem(row,2,new QTableWidgetItem(Global::getQuestion(ans.getQuestionId()).getTitle()));
            ui->tableWidget_2->setItem(row,3,new QTableWidgetItem(QString::number(ans.getPraisedNum())));
            ui->tableWidget_2->setItem(row,4,new QTableWidgetItem(Global::getUser(ans.getUserId()).getName()));
            ui->tableWidget_2->setItem(row,5,new QTableWidgetItem(ans.getTime()));
            for(int col = 0;col<ui->tableWidget_2->columnCount();col++)
                ui->tableWidget_2->item(row,col)->setTextColor(QColor(220,220,220));
            row++;
        }
    }
    if(row == 0)
        ui->tableWidget_2->setItem(0,0,new QTableWidgetItem(QString("未找到相關回答")));
    qDebug()<<"end search by time";
}

(9)通知消息窗口
這裏寫圖片描述

noticewindow.h

#ifndef NOTICEWINDOW_H
#define NOTICEWINDOW_H

#include <QWidget>
#include <vector>
namespace Ui {
class NoticeWindow;
}

class NoticeWindow : public QWidget
{
    Q_OBJECT

public:
    explicit NoticeWindow(QWidget *parent = 0);
    ~NoticeWindow();
    void showNotice();

private slots:


    void on_noticeButton_toggled(bool checked);

    void on_praiseButton_toggled(bool checked);

    void on_focusButton_toggled(bool checked);

    void on_messageButton_toggled(bool checked);


    void on_tableWidget_doubleClicked(const QModelIndex &index);

private:
    Ui::NoticeWindow *ui;
};

#endif // NOTICEWINDOW_H

noticewindow.cpp

#include "noticewindow.h"
#include "ui_noticewindow.h"
#include "global.h"
#include "quesanswindow.h"
#include "replydialog.h"
#include "userdatawindow.h"
#include "commentdialog.h"
NoticeWindow::NoticeWindow(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::NoticeWindow)
{
    ui->setupUi(this);
    QPalette pallete;
    QPixmap pixmap(".//image/bg7.jpg");
    pallete.setBrush(QPalette::Window, QBrush(pixmap));
    this->setPalette( pallete);
    ui->noticeButton->setChecked(true);
    this->showNotice();
}

NoticeWindow::~NoticeWindow()
{
    delete ui;
}

void NoticeWindow::on_noticeButton_toggled(bool checked)
{
    if(checked)
    {
        this->showNotice();
    }

}
void  NoticeWindow::showNotice()
{
    ui->focusButton->setChecked(false);
    ui->praiseButton->setChecked(false);
    ui->messageButton->setChecked(false);

    ui->tableWidget->setRowCount(0);
    ui->tableWidget->setColumnCount(4);
    ui->tableWidget->verticalHeader()->setDefaultSectionSize(40);
    ui->tableWidget->setFont(QFont("微軟雅黑", 10, QFont::Bold ));

    ui->tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
    QStringList header;
    header<<tr("ID")<<tr("標題")<<tr("時間")<<tr("問題ID");
    ui->tableWidget->setHorizontalHeaderLabels(header);
    ui->tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
    ui->tableWidget->setShowGrid(false);
    ui->tableWidget->horizontalHeader()->setStretchLastSection(true);
    ui->tableWidget->setStyleSheet("background-color:rgba(0,0,0,30)");
    ui->tableWidget->horizontalHeader()->setStyleSheet("QHeaderView::section{background:skyblue;}");
    ui->tableWidget->verticalHeader()->setStyleSheet("QHeaderView::section{background:skyblue;}");
    ui->tableWidget->setColumnWidth(1,400);
    int row=0;
    for (vector<Notification>::iterator it = Notifications.begin();it!=Notifications.end();++it)
    {
        Notification notif = *it;

        if(notif.getUserId()==USER.getId() && notif.getType()==Type::Notice)
        {
            ui->tableWidget->setRowCount(row+1);
            ui->tableWidget->setItem(row,0,new QTableWidgetItem(QString::number(notif.getId())));
            ui->tableWidget->setItem(row,1,new QTableWidgetItem(notif.getTitle()));
            ui->tableWidget->setItem(row,2,new QTableWidgetItem(notif.getTime()));
            ui->tableWidget->setItem(row,3,new QTableWidgetItem(QString::number(notif.getQuestionId())));
            for(int col = 0;col<ui->tableWidget->columnCount();col++)
                ui->tableWidget->item(row,col)->setTextColor(QColor(220,220,220));
            //qDebug()<<QString::number(ques.getId())<<" "<<ques.getTitle()<<" "<<ques.getTime()<<" "<<row;
            row++;
        }
    }
}

void NoticeWindow::on_praiseButton_toggled(bool checked)
{
    if(checked)
    {
        ui->focusButton->setChecked(false);
        ui->noticeButton->setChecked(false);
        ui->messageButton->setChecked(false);

        ui->tableWidget->setRowCount(0);
        ui->tableWidget->setColumnCount(4);
        ui->tableWidget->verticalHeader()->setDefaultSectionSize(40);
        ui->tableWidget->setFont(QFont("微軟雅黑", 10, QFont::Bold ));

        ui->tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
        QStringList header;
        header<<tr("ID")<<tr("標題")<<tr("回答")<<tr("時間");
        ui->tableWidget->setHorizontalHeaderLabels(header);
        ui->tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
        ui->tableWidget->setShowGrid(false);
        ui->tableWidget->horizontalHeader()->setStretchLastSection(true);
        ui->tableWidget->setStyleSheet("background-color:rgba(0,0,0,30)");
        ui->tableWidget->horizontalHeader()->setStyleSheet("QHeaderView::section{background:skyblue;}");
        ui->tableWidget->verticalHeader()->setStyleSheet("QHeaderView::section{background:skyblue;}");
        ui->tableWidget->setColumnWidth(1,400);
        int row=0;
        for (vector<Notification>::iterator it = Notifications.begin();it!=Notifications.end();++it)
        {
            Notification notif = *it;

            if(notif.getUserId()==USER.getId() && notif.getType()==Type::Praise)
            {
                ui->tableWidget->setRowCount(row+1);
                ui->tableWidget->setItem(row,0,new QTableWidgetItem(QString::number(notif.getId())));
                ui->tableWidget->setItem(row,1,new QTableWidgetItem(notif.getTitle()));
                ui->tableWidget->setItem(row,2,new QTableWidgetItem(notif.getContent()));
                ui->tableWidget->setItem(row,3,new QTableWidgetItem(notif.getTime()));

                for(int col = 0;col<ui->tableWidget->columnCount();col++)
                    ui->tableWidget->item(row,col)->setTextColor(QColor(220,220,220));
                //qDebug()<<QString::number(ques.getId())<<" "<<ques.getTitle()<<" "<<ques.getTime()<<" "<<row;
                row++;
            }
        }
    }

}

void NoticeWindow::on_focusButton_toggled(bool checked)
{
    if(checked)
    {
        ui->noticeButton->setChecked(false);
        ui->praiseButton->setChecked(false);
        ui->messageButton->setChecked(false);

        ui->tableWidget->setRowCount(0);
        ui->tableWidget->setColumnCount(4);
        ui->tableWidget->verticalHeader()->setDefaultSectionSize(40);
        ui->tableWidget->setFont(QFont("微軟雅黑", 10, QFont::Bold ));

        ui->tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
        QStringList header;
        header<<tr("ID")<<tr("標題")<<tr("時間")<<tr("對方ID");
        ui->tableWidget->setHorizontalHeaderLabels(header);
        ui->tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
        ui->tableWidget->setShowGrid(false);
        ui->tableWidget->horizontalHeader()->setStretchLastSection(true);
        ui->tableWidget->setStyleSheet("background-color:rgba(0,0,0,30)");
        ui->tableWidget->horizontalHeader()->setStyleSheet("QHeaderView::section{background:skyblue;}");
        ui->tableWidget->verticalHeader()->setStyleSheet("QHeaderView::section{background:skyblue;}");
        ui->tableWidget->setColumnWidth(1,400);
        int row=0;
        for (vector<Notification>::iterator it = Notifications.begin();it!=Notifications.end();++it)
        {
            Notification notif = *it;

            if(notif.getUserId()==USER.getId() && notif.getType()==Type::Focused)
            {
                ui->tableWidget->setRowCount(row+1);
                ui->tableWidget->setItem(row,0,new QTableWidgetItem(QString::number(notif.getId())));
                ui->tableWidget->setItem(row,1,new QTableWidgetItem(notif.getTitle()));
                ui->tableWidget->setItem(row,2,new QTableWidgetItem(notif.getTime()));
                ui->tableWidget->setItem(row,3,new QTableWidgetItem(QString::number(notif.getSenderId())));
                //ui->tableWidget->setItem(row,3,new QTableWidgetItem(QString::number(notif.getQuestionId())));
                for(int col = 0;col<ui->tableWidget->columnCount();col++)
                    ui->tableWidget->item(row,col)->setTextColor(QColor(220,220,220));
                //qDebug()<<QString::number(ques.getId())<<" "<<ques.getTitle()<<" "<<ques.getTime()<<" "<<row;
                row++;
            }
        }
    }

}

void NoticeWindow::on_messageButton_toggled(bool checked)
{
    if(checked)
    {
        ui->focusButton->setChecked(false);
        ui->praiseButton->setChecked(false);
        ui->noticeButton->setChecked(false);

        ui->tableWidget->setRowCount(0);
        ui->tableWidget->setColumnCount(3);
        ui->tableWidget->verticalHeader()->setDefaultSectionSize(40);
        ui->tableWidget->setFont(QFont("微軟雅黑", 10, QFont::Bold ));

        ui->tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
        QStringList header;
        header<<tr("ID")<<tr("標題")<<tr("時間");
        ui->tableWidget->setHorizontalHeaderLabels(header);
        ui->tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
        ui->tableWidget->setShowGrid(false);
        ui->tableWidget->horizontalHeader()->setStretchLastSection(true);
        ui->tableWidget->setStyleSheet("background-color:rgba(0,0,0,30)");
        ui->tableWidget->horizontalHeader()->setStyleSheet("QHeaderView::section{background:skyblue;}");
        ui->tableWidget->verticalHeader()->setStyleSheet("QHeaderView::section{background:skyblue;}");
        ui->tableWidget->setColumnWidth(1,400);

        /*因爲迭代器類型搞錯了
         * error: conversion from 'std::vector<Notification>::iterator {aka __gnu_cxx::__normal_iterator<Notification*,
         * std::vector<Notification> >}' to non-scalar type 'std::vector<int, std::allocator<int> >::iterator
         * {aka __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >}' requested
        */
        int row=0;
        for (vector<Notification>::iterator it = Notifications.begin();it!=Notifications.end();++it)
        {
            Notification notif = *it;

            if(notif.getUserId()==USER.getId() && notif.getType()==Type::Message)
            {
                ui->tableWidget->setRowCount(row+1);
                ui->tableWidget->setItem(row,0,new QTableWidgetItem(QString::number(notif.getId())));
                ui->tableWidget->setItem(row,1,new QTableWidgetItem(notif.getTitle()));
                ui->tableWidget->setItem(row,2,new QTableWidgetItem(notif.getTime()));
               // ui->tableWidget->setItem(row,3,new QTableWidgetItem(QString::number(notif.getQuestionId())));
                for(int col = 0;col<ui->tableWidget->columnCount();col++)
                    ui->tableWidget->item(row,col)->setTextColor(QColor(220,220,220));
                //qDebug()<<QString::number(ques.getId())<<" "<<ques.getTitle()<<" "<<ques.getTime()<<" "<<row;
                row++;
            }
        }
    }
}



void NoticeWindow::on_tableWidget_doubleClicked(const QModelIndex &index)
{
    if(ui->noticeButton->isChecked())
    {
        bool* ok = NULL;
        int id =ui->tableWidget->item(index.row(),0)->text().toInt(ok,10);
        int quesId =ui->tableWidget->item(index.row(),3)->text().toInt(ok,10);
        Notification notif = Global::getNotification(id);
        if(notif.getAnswerId()==0)
        {
            QuesAnsWindow *qaw = new QuesAnsWindow;
            qaw->show();
            qaw->showQuesAnswers(quesId);
        }
        else
        {
            CommentDialog *cmtDlg = new CommentDialog;
            this->hide();
            cmtDlg->setAnswerId(notif.getAnswerId());
            cmtDlg->setAnswererId(quesId);
            cmtDlg->showComments();
            cmtDlg->exec();
        }

    }
    else if(ui->praiseButton->isChecked())
    {
        bool* ok = NULL;
        int id =ui->tableWidget->item(index.row(),0)->text().toInt(ok,10);
        Notification notif = Global::getNotification(id);
        int quesId = notif.getQuestionId();
        int ansId = notif.getAnswerId();
        QuesAnsWindow *qaw = new QuesAnsWindow;
        qaw->show();
        qaw->showQuesAnswers(quesId);
        qaw->showAnswer(ansId);

    }
    else if(ui->focusButton->isChecked())
    {
        bool* ok = NULL;
        int senderId =ui->tableWidget->item(index.row(),3)->text().toInt(ok,10);
        UserdataWindow *uw = new UserdataWindow;
        uw->setUserId(senderId);
        uw->show();
        uw->showAllDatas();
        this->hide();
    }
    else
    {
        bool* ok = NULL;
        int id =ui->tableWidget->item(index.row(),0)->text().toInt(ok,10);
        Notification notif = Global::getNotification(id);
        ReplyDialog *rplDlg = new ReplyDialog;
        rplDlg->setNotif(notif);
        rplDlg->showMessage();
        rplDlg->exec();
    }
}

(10)評論窗口
這裏寫圖片描述

commentdialog.h

#ifndef COMMENTDIALOG_H
#define COMMENTDIALOG_H

#include <QDialog>

namespace Ui {
class CommentDialog;
}

class CommentDialog : public QDialog
{
    Q_OBJECT

public:
    explicit CommentDialog(QWidget *parent = 0);
    ~CommentDialog();

    void showComments();

    void setAnswerId(int id);
    int getAnswerId();

    void setAnswererId(int id);
    int getAnswererId();

private slots:
    void on_buttonBox_accepted();

    void on_buttonBox_rejected();

private:
    Ui::CommentDialog *ui;

    int answerId;
    int answererId;

};

#endif // COMMENTDIALOG_H

commentdialog.cpp

#include "commentdialog.h"
#include "ui_commentdialog.h"
#include "global.h"

#include <QMessageBox>
CommentDialog::CommentDialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::CommentDialog)
{
    ui->setupUi(this);
    QPalette pallete;
    QPixmap pixmap(".//image/small.png");
    pallete.setBrush(QPalette::Window, QBrush(pixmap));
    this->setPalette( pallete);
}

CommentDialog::~CommentDialog()
{
    delete ui;
}

void CommentDialog::showComments()
{
    ui->tableWidget->setRowCount(0);
    ui->tableWidget->setColumnCount(3);
    ui->tableWidget->verticalHeader()->setDefaultSectionSize(40);
    ui->tableWidget->setFont(QFont("微軟雅黑", 10, QFont::Bold ));

    ui->tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
    QStringList header;
    header<<tr("評論")<<tr("用戶")<<tr("時間");
    ui->tableWidget->setHorizontalHeaderLabels(header);
    ui->tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
    ui->tableWidget->setShowGrid(false);
    ui->tableWidget->horizontalHeader()->setStretchLastSection(true);
    ui->tableWidget->setStyleSheet("background-color:rgba(0,0,0,30)");
    ui->tableWidget->horizontalHeader()->setStyleSheet("QHeaderView::section{background:skyblue;}");
    ui->tableWidget->verticalHeader()->setStyleSheet("QHeaderView::section{background:skyblue;}");
    ui->tableWidget->setColumnWidth(0,400);
    int row=0;
    for (vector<Notification>::iterator it = Notifications.begin();it!=Notifications.end();++it)
    {
        Notification notif = *it;

        if(notif.getType()==Type::Notice && notif.getAnswerId() == this->getAnswerId())
        {
            ui->tableWidget->setRowCount(row+1);
            ui->tableWidget->setItem(row,0,new QTableWidgetItem(notif.getContent()));
            ui->tableWidget->setItem(row,1,new QTableWidgetItem(Global::getUser(notif.getSenderId()).getName()));
            ui->tableWidget->setItem(row,2,new QTableWidgetItem(notif.getTime()));

            for(int col = 0;col<ui->tableWidget->columnCount();col++)
                ui->tableWidget->item(row,col)->setTextColor(QColor(220,220,220));
            //qDebug()<<QString::number(ques.getId())<<" "<<ques.getTitle()<<" "<<ques.getTime()<<" "<<row;
            row++;
        }
    }
}

void CommentDialog::setAnswerId(int id)
{
    this->answerId = id;
}

int CommentDialog::getAnswerId()
{
    return this->answerId;
}
void CommentDialog::setAnswererId(int id)
{
    this->answererId = id;
}

int CommentDialog::getAnswererId()
{
    return this->answererId;
}
void CommentDialog::on_buttonBox_accepted()
{
    QString content = ui->textEdit->toPlainText();
    if(content!="")
    {
        Notification notif;

        int id = Notifications.size()+1;
        int userId = this->getAnswererId();
        int senderId = USER.getId();
        QDateTime time = QDateTime::currentDateTime();//獲取系統現在的時間
        QString timestr = time.toString("yyyy-MM-dd hh:mm:ss ddd"); //設置顯示格式
        QString title = QString("%1 評論了你的回答 ").arg(USER.getName());
        notif.created(id,userId,content,timestr);

        notif.setQuestionId(Global::getAnswer(this->getAnswerId()).getQuestionId());
        notif.setAnswerId(this->getAnswerId());
        notif.setSenderId(senderId);
        notif.setType(1);
        notif.setTitle(title);

        Global::insert(notif);
    }
    else
    {
        QMessageBox fail(QMessageBox::NoIcon, "失敗", "請輸入評論內容");
        fail.addButton("確定", QMessageBox::AcceptRole);
        fail.exec();
    }

}

void CommentDialog::on_buttonBox_rejected()
{
    this->close();
}

(11)邀請他人頁面
這裏寫圖片描述

invitedialog.h

#ifndef INVITEDIALOG_H
#define INVITEDIALOG_H

#include <QDialog>

namespace Ui {
class InviteDialog;
}

class InviteDialog : public QDialog
{
    Q_OBJECT

public:
    explicit InviteDialog(QWidget *parent = 0);
    ~InviteDialog();
    void showFocus();
    void showFollowed();
    void showAll();

    int getQuestionId();
    void setQuestionId(int id);
private slots:
    void on_tableWidget_doubleClicked(const QModelIndex &index);



    void on_radioButton_clicked();

    void on_radioButton_2_clicked();

    void on_radioButton_3_clicked();


private:
    Ui::InviteDialog *ui;
    int questionId;
};

#endif // INVITEDIALOG_H

invitedialog.cpp

#include "invitedialog.h"
#include "ui_invitedialog.h"
#include "global.h"

#include <QMessageBox>

InviteDialog::InviteDialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::InviteDialog)
{
    ui->setupUi(this);
    QPalette pallete;
    QPixmap pixmap(".//image/small.png");
    pallete.setBrush(QPalette::Window, QBrush(pixmap));
    this->setPalette( pallete);

    ui->tableWidget->setRowCount(0);
    ui->tableWidget->setColumnCount(4);
    ui->tableWidget->verticalHeader()->setDefaultSectionSize(40);
    ui->tableWidget->setFont(QFont("微軟雅黑", 10, QFont::Bold ));

    ui->tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
    QStringList header;
    header<<tr("ID")<<tr("名稱")<<tr("回答數")<<tr("獲贊數");
    ui->tableWidget->setHorizontalHeaderLabels(header);
    ui->tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
    ui->tableWidget->setShowGrid(false);
    ui->tableWidget->horizontalHeader()->setStretchLastSection(true);
    ui->tableWidget->setStyleSheet("background-color:rgba(0,0,0,30)");
    ui->tableWidget->horizontalHeader()->setStyleSheet("QHeaderView::section{background:skyblue;}");
    ui->tableWidget->verticalHeader()->setStyleSheet("QHeaderView::section{background:skyblue;}");

    this->showFocus();
}

InviteDialog::~InviteDialog()
{
    delete ui;
}
int InviteDialog::getQuestionId()
{
    return this->questionId;
}
void InviteDialog::setQuestionId(int id)
{
    this->questionId=id;
}

void InviteDialog::showFocus()
{
    std::vector<int> focuslist = USER.getFocusList();
    int row=0;
    for(std::vector<int>::iterator it = focuslist.begin();it!=focuslist.end();++it)
    {
        User user = Global::getUser(*it);
        ui->tableWidget->setRowCount(row+1);
        ui->tableWidget->setItem(row,0,new QTableWidgetItem(QString::number(user.getId())));
        ui->tableWidget->setItem(row,1,new QTableWidgetItem(user.getName()));
        ui->tableWidget->setItem(row,2,new QTableWidgetItem(user.getAnswerList().size()));
        ui->tableWidget->setItem(row,3,new QTableWidgetItem(user.getPraisedNum()));
        for(int col = 0;col<ui->tableWidget->columnCount();col++)
            ui->tableWidget->item(row,col)->setTextColor(QColor(220,220,220));
        row++;
    }

}

void InviteDialog::showFollowed()
{
    std::vector<int> followedlist = USER.getFollowedList();
    int row=0;
    for(std::vector<int>::iterator it = followedlist.begin();it!=followedlist.end();++it)
    {
        User user = Global::getUser(*it);
        ui->tableWidget->setRowCount(row+1);
        ui->tableWidget->setItem(row,0,new QTableWidgetItem(QString::number(user.getId())));
        ui->tableWidget->setItem(row,1,new QTableWidgetItem(user.getName()));
        ui->tableWidget->setItem(row,2,new QTableWidgetItem(user.getAnswerList().size()));
        ui->tableWidget->setItem(row,3,new QTableWidgetItem(user.getPraisedNum()));
        for(int col = 0;col<ui->tableWidget->columnCount();col++)
            ui->tableWidget->item(row,col)->setTextColor(QColor(220,220,220));
        row++;
    }
}

void InviteDialog::showAll()
{
    int row=0;
    for(std::vector<User>::iterator it = Users.begin();it!=Users.end();++it)
    {
        User user = *it;

        if(USER.getId()!=user.getId())
        {
            ui->tableWidget->setRowCount(row+1);
            ui->tableWidget->setItem(row,0,new QTableWidgetItem(QString::number(user.getId())));
            ui->tableWidget->setItem(row,1,new QTableWidgetItem(user.getName()));
            ui->tableWidget->setItem(row,2,new QTableWidgetItem(user.getAnswerList().size()));
            ui->tableWidget->setItem(row,3,new QTableWidgetItem(user.getPraisedNum()));
            for(int col = 0;col<ui->tableWidget->columnCount();col++)
                ui->tableWidget->item(row,col)->setTextColor(QColor(220,220,220));
            row++;
        }
    }
}

void InviteDialog::on_tableWidget_doubleClicked(const QModelIndex &index)
{
    Notification notif;
    bool* ok = NULL;
    int id = Notifications.size()+1;
    int userId =ui->tableWidget->item(index.row(),0)->text().toInt(ok,10);
    int senderId = USER.getId();
    int questionId = this->getQuestionId();
    QDateTime time = QDateTime::currentDateTime();//獲取系統現在的時間
    QString timestr = time.toString("yyyy-MM-dd hh:mm:ss ddd"); //設置顯示格式
    QString title = QString("%1 邀請你回答問題").arg(USER.getName());
    QString content = Global::getQuestion(questionId).getTitle();
    notif.created(id,userId,content,timestr);
    notif.setQuestionId(questionId);
    notif.setAnswerId(0);
    notif.setSenderId(senderId);
    notif.setType(1);
    notif.setTitle(title);

    Global::insert(notif);

    QMessageBox fail(QMessageBox::NoIcon, "成功", "邀請已發送");
    fail.addButton("確定", QMessageBox::AcceptRole);
    fail.exec();
    this->close();
}


void InviteDialog::on_radioButton_clicked()
{
    this->showFocus();

}

void InviteDialog::on_radioButton_2_clicked()
{
    this->showFollowed();
}

void InviteDialog::on_radioButton_3_clicked()
{
    this->showAll();
}

(12)私信(查看別人資料是可以給人私信)

這裏寫圖片描述
這個忘記加圖片背景了。。。
messagedialog.h

#ifndef MESSAGEDIALOG_H
#define MESSAGEDIALOG_H

#include <QDialog>

namespace Ui {
class MessageDialog;
}

class MessageDialog : public QDialog
{
    Q_OBJECT

public:
    explicit MessageDialog(QWidget *parent = 0);
    ~MessageDialog();

    int getReceiverId();
    void setReceiverId(int id);

private slots:
    void on_buttonBox_accepted();

    void on_buttonBox_rejected();

private:
    Ui::MessageDialog *ui;
    int receiverId;
};

#endif // MESSAGEDIALOG_H

messagedialog.cpp

#include "messagedialog.h"
#include "ui_messagedialog.h"
#include "global.h"
#include <QMessageBox>

MessageDialog::MessageDialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::MessageDialog)
{
    ui->setupUi(this);
}

MessageDialog::~MessageDialog()
{
    delete ui;
}
int MessageDialog::getReceiverId()
{
    return this->receiverId;
}
void MessageDialog::setReceiverId(int id)
{
    this->receiverId=id;
}

void MessageDialog::on_buttonBox_accepted()
{
    QString content = ui->textEdit->toPlainText();
    if(content!="")
    {
        Notification notif;

        int id = Notifications.size()+1;
        int userId = this->getReceiverId();
        int senderId = USER.getId();
        QDateTime time = QDateTime::currentDateTime();//獲取系統現在的時間
        QString timestr = time.toString("yyyy-MM-dd hh:mm:ss ddd"); //設置顯示格式
        QString title = QString("%1 給你發了一條私信").arg(USER.getName());
        notif.created(id,userId,content,timestr);
        notif.setQuestionId(0);
        notif.setAnswerId(0);
        notif.setSenderId(senderId);
        notif.setType(4);
        notif.setTitle(title);

        Global::insert(notif);
    }
    else
    {
        QMessageBox fail(QMessageBox::NoIcon, "失敗", "請輸入內容");
        fail.addButton("確定", QMessageBox::AcceptRole);
        fail.exec();
    }

}

void MessageDialog::on_buttonBox_rejected()
{
    this->close();
}

(13)回覆窗口
這裏寫圖片描述
replydialog.h

#ifndef REPLYDIALOG_H
#define REPLYDIALOG_H
#include "notification.h"
#include <QDialog>

namespace Ui {
class ReplyDialog;
}

class ReplyDialog : public QDialog
{
    Q_OBJECT

public:
    explicit ReplyDialog(QWidget *parent = 0);
    ~ReplyDialog();

    void setNotif(Notification notif);
    Notification getNotif();
    void showMessage();

private slots:
    void on_buttonBox_accepted();

private:
    Ui::ReplyDialog *ui;
    Notification notif;
};

#endif // REPLYDIALOG_H

replydialog.cpp

#include "replydialog.h"
#include "ui_replydialog.h"
#include "global.h"

#include <QMessageBox>
ReplyDialog::ReplyDialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::ReplyDialog)
{
    ui->setupUi(this);
    QPalette pallete;
    QPixmap pixmap(".//image/small.png");
    pallete.setBrush(QPalette::Window, QBrush(pixmap));
    this->setPalette( pallete);
}

ReplyDialog::~ReplyDialog()
{
    delete ui;
}
void ReplyDialog::setNotif(Notification notif)
{
    this->notif=notif;
}

Notification ReplyDialog::getNotif()
{
    return this->notif;
}
void ReplyDialog::showMessage()
{//原本把這部分放在構造函數裏了,但是老師出錯,原因是這裏面用到了成員變量,而構造時還沒有賦值,所以一直是金疙瘩,應該賦值notif後在show
    ui->textBrowser->setText(this->notif.getContent());
    ui->label->setText(Global::getUser(this->notif.getSenderId()).getName());
    ui->label_2->setText(USER.getName());
}

void ReplyDialog::on_buttonBox_accepted()
{
    QString content = ui->textEdit->toPlainText();
    if(content != "")
    {
        Notification notif;

        int id = Notifications.size()+1;
        int userId = this->notif.getSenderId();
        int senderId = USER.getId();
        QDateTime time = QDateTime::currentDateTime();//獲取系統現在的時間
        QString timestr = time.toString("yyyy-MM-dd hh:mm:ss ddd"); //設置顯示格式
        QString title = QString("%1 給你發了一條私信").arg(USER.getName());
        notif.created(id,userId,content,timestr);
        notif.setQuestionId(0);
        notif.setAnswerId(0);
        notif.setSenderId(senderId);
        notif.setType(4);
        notif.setTitle(title);

        Global::insert(notif);
    }
    else
    {
        QMessageBox fail(QMessageBox::NoIcon, "失敗", "請輸入內容");
        fail.addButton("確定", QMessageBox::AcceptRole);
        fail.exec();
    }
}

(14)修改密碼
這裏寫圖片描述
changeprofile.h(名字取錯了,但是改起來挺麻煩就沒改了)

#ifndef CHANGEPROFILE_H
#define CHANGEPROFILE_H

#include <QDialog>

namespace Ui {
class ChangeProfile;
}

class ChangeProfile : public QDialog
{
    Q_OBJECT

public:
    explicit ChangeProfile(QWidget *parent = 0);
    ~ChangeProfile();

private slots:
    void on_buttonBox_accepted();

    void on_buttonBox_rejected();

private:
    Ui::ChangeProfile *ui;
};

#endif // CHANGEPROFILE_H

changeprofile.cpp

#include "changeprofile.h"
#include "ui_changeprofile.h"
#include "global.h"

#include <QMessageBox>
ChangeProfile::ChangeProfile(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::ChangeProfile)
{
    ui->setupUi(this);
    ui->lineEdit_2->setEchoMode(QLineEdit::Password);
    ui->lineEdit_3->setEchoMode(QLineEdit::Password);

    QPalette pallete;
    QPixmap pixmap(".//image/small.png");
    pallete.setBrush(QPalette::Window, QBrush(pixmap));
    this->setPalette( pallete);
}

ChangeProfile::~ChangeProfile()
{
    delete ui;
}

void ChangeProfile::on_buttonBox_accepted()
{
    QString oldPass = ui->lineEdit->text();
    if(oldPass != USER.getPassword())
    {
        QMessageBox fail(QMessageBox::NoIcon, "失敗", "原密碼錯誤");
        fail.addButton("確定", QMessageBox::AcceptRole);
        fail.exec();
    }
    else
    {
        QString newPass = ui->lineEdit_2->text();
        QString newPassCf = ui->lineEdit_3->text();
        if (newPass != newPassCf)
        {
            QMessageBox fail(QMessageBox::NoIcon, "失敗", "兩次密碼不一致");
            ui->lineEdit_2->clear();
            ui->lineEdit_3->clear();
            fail.addButton("確定", QMessageBox::AcceptRole);
            fail.exec();
        }
        else
        {
            USER.setPassword(newPass);
            Global::update(USER);
        }
    }
}

void ChangeProfile::on_buttonBox_rejected()
{
    this->close();
}

(15)修改用戶名
這裏寫圖片描述
圖中原用戶名沒有顯示。。下面的代碼中以及改了。

changename.h

#ifndef CHANGENAME_H
#define CHANGENAME_H

#include <QDialog>

namespace Ui {
class ChangeName;
}

class ChangeName : public QDialog
{
    Q_OBJECT

public:
    explicit ChangeName(QWidget *parent = 0);
    ~ChangeName();

private slots:
    void on_buttonBox_accepted();

    void on_buttonBox_rejected();

private:
    Ui::ChangeName *ui;
};

#endif // CHANGENAME_H

changename.cpp

#include "changename.h"
#include "ui_changename.h"
#include "global.h"
ChangeName::ChangeName(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::ChangeName)
{
    ui->setupUi(this);
    ui->label->setText(USER.getName());
    QPalette pallete;
    QPixmap pixmap(".//image/small.png");
    pallete.setBrush(QPalette::Window, QBrush(pixmap));
    this->setPalette( pallete);
}

ChangeName::~ChangeName()
{
    delete ui;
}

void ChangeName::on_buttonBox_accepted()
{
    QString newName = ui->lineEdit->text();
    USER.setName(newName);
    Global::update(USER);
}

void ChangeName::on_buttonBox_rejected()
{
    this->close();
}

至此源代碼都已經貼出,UI方面就只能靠自己看圖咯,或者下載完整源碼。

完成這個項目中遇到的教訓
1. “基礎設施”在前期要打好,後期就會事半功倍。這個基礎設計並不僅僅指的是編程基礎理論基礎,比如我對於數據庫操作的瞭解較少就遇到了很多新手常犯的錯誤,而且這個基礎還指的是整個系統初期所做的一些事,比如類的成員有哪些,成員函數,還有一些常用的函數,比如按ID查詢用戶、問題答案這種前期就要寫完善,否則到了後期如果還有錯很難找到。成員變量沒增加一個就得修改數據庫中的一部分代碼,沒修改一次就增加了出錯的機率。因此一開始儘量要想完善自己要做成什麼樣子,這個格局一開始就要打好,會在之後的工作中很方便。比如我一開始就想到自己需要加“粉絲”這個變量,因此在定義“focuslist”的時候就一起定義了“followedlist”。但是由於一開始沒有想太遠對於問題和回答對象的保存,所以之後才加的“answerlist”和“asklist”。
2. 由於將操作符重載定義寫在了.h文件中,導致報了multiple definition的錯誤。應該講重載的定義寫在.cpp的,然後在類的定義中將操作符重載聲明爲友元。或者還能夠通過在.h中在聲明直接加上incline關鍵字。
3. 定義全局變量的過程也是充滿曲折。一開始我只是新建了一個global.h文件,沒有新建global.cpp,使用了extern關鍵字聲明變量也沒有用,後來又新建了一個Global類,裏面放入全局變量,每個變量都是static的,但是還是編譯報錯。後來通過問同學才知道還得新建一個global.cpp,在裏面再定義每個全局變量,只是不需要再加extern了。我兩種全局變量的方法都用了,全局函數定義在Global類裏,像所有問題,答案這種容器定義了extern。爲了保持封裝性,網上推薦使用使用Global類這種方式,使用extern則破壞了程序的封裝性。
4. 新定義的窗口總是閃退。通過網上查詢得知是因爲我將窗口對象定義在棧中,每次都被釋放了,而爲了保持窗口應該定義在堆中。比如”Dialog dlg”應改成 “Dialog *dlg = new Dialog” 。
5. TableWidget的列數和我自己實現的數量不一樣導致打卡那個窗口總是程序異常終止。TableWidget的使用需要十分小心,因爲有多處使用,所以我在複製代碼之後總是忘記“因地制宜”,沒有修改行數導致運行不了。
6. 迭代器類型使用錯誤。因爲我在類裏定義的容器都是存的int類型的id,但是我將所有問題,答案等都是放在各地對應的容器,比如所有通知對象放在”vector<Notification>Notifications”中。導致我有次弄混,導致報了一個錯:
“error: conversion from 'std::vector<Notification>::iterator {aka __gnu_cxx::__normal_iterator<Notification* std::vector<Notification> >}' to non-scalar type 'std::vector<int, std::allocator<int> >::iterator
7. 說到迭代器還有一個錯誤特別難找,在遍歷用戶的關注列表時我開始使用的下面這個循環
for(vector<int>::iterator it= USER.getFocusList().begin(); it != USER.getFocusList().end(); ++it)”,但是總是輸出一些奇怪的數字,我開始以爲只是越界了,以爲這個focuslist的end不對勁,所以開始我在網上查找解決方案的時候搜的是解決容器迭代器的越界問題,於是找到了使用at的方法,也就是相當於使用下標的方式,用一個i從0到USER.getFocusList().size(),然後提取USER.getFocusList().at(i)。問題是沒有了,但是原因不是這個,原因是因爲USER.getFocusList()是得到focuslist的一個副本,並不是得到focuslist本身,裏面的值是一樣但是保存的地址不同,每次使用USER.getFocusList()得到的也不是同一個變量,因此在USER.getFocusList().begin()USER.getFocusList().end()之間可能還有很多位置的東西,因爲是一個容器的開頭,另一個容器的結尾,自然這樣遍歷下去會輸出一些異常的數字。所有我在for循環開始之前先定義一個臨時容器保存USER.getFocusList(),然後for循環遍歷這個臨時容器,這樣就解決了這個問題。
8. 關於get和set函數我還犯了一個類似的錯誤,原因還是忘記get函數得到的只是一個分身,所有隻是改變分身對真身不會有任何影響。
9. 沒有給成員變量賦值就調用了需要操作成員變量的成員函數。我希望在一個窗口打開的時候就展示數據,所以在構造函數中就寫了展示函數show(),但是當我運行打開窗口的時候發現數據總是同一個人的,反正不是我所需要的那個人。後來發現是因爲我是在構造函數執行了之後才賦值成員變量,所有展示出來的數據也不是我想要的數據了。因此在構造函數中我們應該儘量避免執行一些需要操作成員變量的函數,因爲構造函數總是在聲明的時候就執行了,而這個時候成員變量不一定賦值了。
10. 由於純虛函數沒有在子類中實現導致vtable reference,這個錯誤是很經典的,有時候忘記實現了就會編譯錯誤,因爲錯了一兩次後就基本不會犯了。
11. 關於數據庫的方面的錯誤犯了很多。首先就是誤用了sql裏面的關鍵字,比如password就是一個,time也是,使用了這些關鍵字肯定會報錯。然後就是parameter count mismatch,原因是因爲我在聲明數據庫的時候多了或者少了一個逗號,又或者是在插入或更新是sql語句中多了個問號。關於數據庫的知識還是得先多學習一下再上手可以少走很多彎路,節約一些時間,光是數據庫的錯誤就佔了我前期找錯的一半的時間。

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