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(q
在Python中,我们可以利用skfuzzy库来构建一个模糊逻辑系统,它适用于处理不确定性问题,如餐馆的服务品质和食品质量对小费支付额度的影响。首先,我们需要了解几个基本的概念: 1. **模糊集**:模糊集允许我们量化不确定的概念,例如“食物质量很好”可以用一个介于0(极差)和1(极好)之间的模糊度来表示。 2. **模糊变量**:比如服务质量(Good, Average, Poor)和食品质量(Excellent, Good, Average, Poor),这些都是模糊变量。 3. **模糊规则**:基于经验和领域知识制定规则,比如“如果食物质量非常好,那么小费可能是20%”,这里涉及的是隶属函数(如三角形、梯形等)的设置。 下面是一个简单的例子,展示如何使用skfuzzy创建这个系统: ```python import skfuzzy as fuzz from skfuzzy import control as ctrl # 创建模糊变量 quality = ctrl.Antecedent(universe=[1, 5], label='food_quality') service = ctrl.Antecedent(universe=[1, 5], label='service_quality') # 设置模糊集合 quality['Excellent'] = fuzz.trapmf(quality.universe, [1, 2, 3, 4]) quality['Good'] = fuzz.trimf(quality.universe, [2, 3, 4]) quality['Average'] = fuzz.trimf(quality.universe, [3, 4, 5]) quality['Poor'] = fuzz.trapmf(quality.universe, [4, 5, 5, 5]) service['Excellent'] = fuzz.trimf(service.universe, [1, 4, 5]) service['Good'] = fuzz.trimf(service.universe, [2, 4, 5]) service['Average'] = fuzz.trimf(service.universe, [3, 4, 5]) service['Poor'] = fuzz.trimf(service.universe, [4, 5, 5]) # 创建结果变量 tip_percentage = ctrl.Consequent(universe=[0, 50], label='tip_percentage') # 定义模糊规则 rule1 = ctrl.Rule(quality['Excellent'] & service['Excellent'], tip_percentage['Very High']) rule2 = ctrl.Rule((quality['Good'] | quality['Excellent']) & service['Good'], tip_percentage['High']) ... (添加更多规则) # 设定控制器 system = ctrl.ControlSystem(rules=rules) controller = ctrl.ControlSystemSimulation(system) # 输入模拟值(假设) input_service = 4 input_food = 3 # 调用模糊推理 controller.input['service_quality'] = input_service controller.input['food_quality'] = input_food controller.compute() # 获取结果 tip_percentage_output = controller.output['tip_percentage'] print(f"根据输入的服务质量和食品质量,预计的小费比例为 {tip_percentage_output}%") ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值