RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / user-197815

Matty's questions

Martin Hope
Matty
Asked: 2020-12-27 23:15:21 +0000 UTC

用于处理笔记的程序的代码审查

  • 13

你好。我正在编写一个用于处理笔记的小程序。现在已经实现了最低限度的功能:可以创建、编辑和删除注释。对于 GUI,我有 Qt,基础是 SQLite。一般来说,一切正常,做我想做的事。但是我的编程经验趋于零,所以我怀疑有很多缺点我无法修复,因为我不知道去哪里找。我希望您指出所有明显的错误/问题/缺点。对从划分到类的逻辑到可能的内存泄漏的一切都感兴趣。

现在基本上有 12 个类:

  • 4 个窗口:MattyNotesMainWindow, MattySettingsDialog, addNoteDialog,MattyMessageBox
  • 使用数据库的类DbManager
  • 用于编写 SQL 查询的类QueryConstructor
  • 注解类本身MattyNote
  • 用于可视化显示注释的构造函数类MattyGroupBox
  • 排序和显示笔记的类NoteHolder
  • css控制类MattyStyleSheetEditor
  • 用于存储字符串和字符的类Constants
  • 手表MattyClocks

我知道不太可能有人会校对所有代码,因此也许您可以查看类及其方法并说出哪些是多余的,或者查看任何一个类并指出其中的缺陷。

例如连接数据库、编辑已有笔记、从数据库中删除所有笔记等功能:

bool DbManager::connect(const QString & path)
{
    MattyNotesDb = QSqlDatabase::addDatabase("QSQLITE");
    MattyNotesDb.setDatabaseName(path);

    if(QFile::exists(path))
    {
        if (!MattyNotesDb.open())
        {
            showIsNotOpenedError();
            MattyNotesDb.close();

            return false;
        }
        else
        {
            PathToDb = MattyNotesDb.databaseName();
        }

        return true;
    }
    else
    {
        return false;
    }
}

bool DbManager::editNote(MattyNote & Note, int NoteId)
{
    if (connected())
    {
        QueryConstructor Edit;
        Edit.setTableName(QStringLiteral("Notes"));

        Edit.addWhereFieldValue(QStringLiteral("NoteId"), QString::number(NoteId));

        QMap<QString, QString> NoteTemp;
        NoteTemp["NoteTitle"] = "\'" + Note.getTitle() + "\'";
        NoteTemp["NoteType"] = "\'" + Note.getType() + "\'";
        NoteTemp["NoteText"] = "\'" + Note.getText() + "\'";
        NoteTemp["EventTime"] = "\'" + Note.getEventTime() + "\'";
        NoteTemp["EventDate"] = "\'" + Note.getEventDate() + "\'";
        NoteTemp["CrTime"] = "\'" + Note.getCrTime() + "\'";
        NoteTemp["CrDate"] = "\'" + Note.getCrDate() + "\'";
        NoteTemp["TypeId"] = QString::number(Note.getTypeId());

        Edit.setWhatToSetFieldValue(NoteTemp); //

        QSqlQuery editNoteQuery;
        return editNoteQuery.exec(Edit.constructUpdateQuery());
    }
    else
    {
        return false;
    }
}

QVector<MattyNoteRow> DbManager::showNotes()
{
    if (connected())
    {
        QVector<MattyNoteRow> VectorOfNoteRows;

        QueryConstructor SelectAllNotes;
        SelectAllNotes.setTableName(QStringLiteral("Notes"));
        SelectAllNotes.setOrderByClause("NoteId", Descending);

        QSqlQuery getAllNotesQuery(MattyNotesDb);

        if( getAllNotesQuery.exec(SelectAllNotes.constructSelectQuery()))
        {
            while (getAllNotesQuery.next())
            {
                MattyNoteRow Row;

                Row.NoteId=getAllNotesQuery.value("NoteId").toInt();
                Row.NoteTitle=getAllNotesQuery.value("NoteTitle").toString();
                Row.NoteType=getAllNotesQuery.value("NoteType").toString();
                Row.NoteText=getAllNotesQuery.value("NoteText").toString();
                Row.EventTime=getAllNotesQuery.value("EventTime").toString();
                Row.EventDate=getAllNotesQuery.value("EventDate").toString();
                Row.CrTime=getAllNotesQuery.value("CrTime").toString();
                Row.CrDate=getAllNotesQuery.value("CrDate").toString();
                Row.TypeId=getAllNotesQuery.value("TypeId").toInt();

                VectorOfNoteRows.push_back(Row);
            }
        }
        else
        {
            QMessageBox::critical(NULL, QObject::tr("Error"), getAllNotesQuery.lastError().text());
        }

        return VectorOfNoteRows;
    }
    else
    {
        return QVector<MattyNoteRow>();
    }
}

将注释发送到表单:

    void NoteHolder::publishNotes(QWidget* ParentWidget)
    {
        erasePublishedNotes(ParentWidget);

        getAllNotes();

        QVector<class MattyNote>::iterator NoteNumber;
        int i;
        for (NoteNumber = ListOfAllNotes.begin(), i=0; NoteNumber < ListOfAllNotes.end();NoteNumber++, i++)
        {

            MattyGroupBox* MyGroupBox = new MattyGroupBox(*NoteNumber, ParentWidget);

            ParentWidget->layout()->addWidget(MyGroupBox);
        }
    }

void NoteHolder::erasePublishedNotes(QWidget* ParentWidget)
{
    MattyGroupBox* MgbTemp;
    while ((MgbTemp = ParentWidget->findChild<MattyGroupBox*>()) != 0)
    {
        delete MgbTemp;
    }

    QGroupBox* GbTemp;
    while ((GbTemp = ParentWidget->findChild<QGroupBox*>()) != 0)
    {
        delete GbTemp;
    }
}

void NoteHolder::getAllNotes()
{
    TotalNoteCount = 0;

    if (!ListOfAllNotes.isEmpty())
        ListOfAllNotes.clear();

    QVector<struct MattyNoteRow> ListOfRows = DbManager::showNotes();

    for (int i = 0; i < ListOfRows.length();i++)
    {
        MattyNote TempNote(ListOfRows[i]);
        ListOfAllNotes.append(TempNote);
        TotalNoteCount++;
    }
}

整个源代码可以在这里看到:GitHub

分离成类、它们的方法、调用、依赖关系等。这里:doxygen

c++
  • 2 个回答
  • 10 Views
Martin Hope
Matty
Asked: 2020-12-21 20:02:27 +0000 UTC

Qt SQLite 通过字段名称访问选择结果

  • 1

现在我的数据库调用如下所示:

   QVector<QStringList> VectorOfRecords;

        QueryConstructor SelectAll;
        SelectAll.setTableName(QStringLiteral("TableName"));
        SelectAll.setOrderByClause("Id", Descending);

        QSqlQuery getRecordsQuery(Database);

        if( getRecordsQuery.exec(SelectAll.constructSelectQuery()))
        {
            while (getRecordsQuery.next())
            {
                QStringList Row;
                for (int i = 0;i < 9;i++)
                {
                    Row.push_back(getRecordsQuery.value(i).toString());
                }
                VectorOfRecords.push_back(Row);
            }
        }
        else
        {
            QMessageBox::critical(NULL, QObject::tr("Error"), getRecordsQuery.lastError().text());
        }

QueryConstructor 是我的类,在此示例中,它请求显示整个表。

我想更换这个

getRecordsQuery.value(i)

不是通过索引,而是通过名称来寻址。因为在我看来,使用数字在某种程度上是不可靠和不可读的。我怎样才能做到这一点?所以一切正常,但我想制作一个更灵活的系统。

c++
  • 1 个回答
  • 10 Views
Martin Hope
Matty
Asked: 2020-12-16 00:53:08 +0000 UTC

Qt 数据库的相对路径。QSqlQuery 错误“没有这样的表。无法执行语句”

  • 2

我有一个项目要从 Visual Studio 迁移到 QtCreator。编译器相应地改变。现在是使用数据库的问题。所有这些都在工作室工作,但我不明白 QtCreator 和 MinGW 不喜欢什么。具体来说,问题归结为在处理 SQL 查询时,它没有看到表。如果您查看 SQLiteManager,那么所有表都已就位,并且执行查询并提供所需的输出。

问题在这里:

QVector<QStringList> DbManager::showNotes()
{
    if (MattyNotesDb.isOpen())
    {
        QVector<QStringList> VectorOfNotes;

        QueryConstructor SelectAll;
        SelectAll.setTableName(QStringLiteral("Notes"));
        SelectAll.setOrderByClause("NoteId", Descending);

        QSqlQuery getNotesQuery;

        if( getNotesQuery.exec(SelectAll.constructSelectQuery())) // exec возвращает false
        {
            while (getNotesQuery.next()) // соответственно тоже возвращает false
            {
                QStringList Fields;
                for (int i = 0;i < 9;i++)
                {
                    Fields.push_back(getNotesQuery.value(i).toString());
                }
                VectorOfNotes.push_back(Fields);
            }
        }
        else
        {
            QMessageBox::critical(NULL, QObject::tr("Error"), getNotesQuery.lastError().text()); // no such table. Unable to execute statement
        }

        return VectorOfNotes;
    }
    else
    {
        showIsNotOpenError();
        return QVector<QStringList>();
    }
}

数据库连接:

bool DbManager::connect(const QString & path)
{
    MattyNotesDb = QSqlDatabase::addDatabase("QSQLITE");
    MattyNotesDb.setDatabaseName(path); // path="MattyNotes.sqlite"

    if(QFile::exists(path)) // true
    {
        if (!MattyNotesDb.open()) // open=true, то есть if(false)
        {
            QMessageBox::critical(NULL, QObject::tr("Error"), MattyNotesDb.lastError().text());
            MattyNotesDb.close();

            return false;
        }

        return true;
    }
    else
    {
        return false;
    }
}

提出要求:

QString QueryConstructor::constructSelectQuery()
{
    QString ResultQuery = "";

    if (TableName != "")
    {
        ResultQuery.append("SELECT ");

        if (WhatToSelectFieldNames.isEmpty())
        {
            ResultQuery.append("*");
        }
        else
        {
            for (int i = 0;i < WhatToSelectFieldNames.length()-1;i++)
            {
                ResultQuery.append(" " + WhatToSelectFieldNames[i] + ",");
            }
            ResultQuery.append(WhatToSelectFieldNames.last());
        }
        ResultQuery.append(" FROM " + TableName + constructWhereEqualsClause() + " " + OrderByClause);
    }
    return ResultQuery; // "SELECT * FROM Notes  ORDER BY NoteId DESC; " 
}

UPD: 问题出在文件路径中。如果您手动输入完整路径,则一切正常。

一。

 QString PathToDb = QCoreApplication::applicationDirPath() + "/MattyNotes.sqlite";

该选项最终将 PathToDb 变量设置为 "C:/Users/Matty/Documents/QtCreator/build-MattyNotes-Desktop_Qt_5_7_1_MinGW_32bit-Debug/debug/MattyNo" 文件夹是正确的,但为什么被截断了?

2.

QString PathToDb = QDir::currentPath() + "/MattyNotes.sqlite";

这个选项赋值为“C:/Users/Matty/MattyNotes.sqlite” 一般来说,我想知道中间文件夹去了哪里。

3.

QString PathToDb = QFileInfo(".").absolutePath() + "/MattyNotes.sqlite";

此选项给出“C:/Users/MattyNotes.sqlite”

发生了什么?如何只指定一个相对路径,以便一切都在不同的机器上运行?

还有一个问题:为什么

if(QFile::exists(path)) // true
if (!MattyNotesDb.open()) // open=true, то есть if(false)

如果数据库实际上没有打开,这些行是否返回 true?

c++
  • 1 个回答
  • 10 Views
Martin Hope
Matty
Asked: 2020-10-30 07:15:48 +0000 UTC

创建采用自定义类的成员函数的问题

  • 2

有一个类继承了QGroupBox(不知道有没有关系),还有一个类就是简单的为他们存储数据和几个函数。我需要将第二个类的实例传递给第一个类的方法。

MattyGroupBox.h

#ifndef MATTYGROUPBOX_H
#define MATTYGROUPBOX_H

    public QGroupBox
{
public:
    MattyGroupBox();
    //void fillFrame(MattyNote & ThisNote);
    ~MattyGroupBox();
private:
    void buildFrame();
    QLabel* NoteTitleLabel;
    QLabel* NoteTypeLabel;
    QLabel* NoteCrTimeAndDateLabel;
    QLabel* NoteEventTimeAndDateLabel;
    QLabel* NoteTextLabel;
    QSpacerItem* horizontalSpacer_1;
    QSpacerItem* horizontalSpacer_2;
    QSpacerItem* verticalSpacer;
    QPushButton* editNoteButton;
    QPushButton* deleteNoteButton;
    QHBoxLayout* horizontalLayout_1;
    QHBoxLayout* horizontalLayout_2;
    QVBoxLayout *verticalLayout;
    QGridLayout *gridLayout;

};

#endif // MATTYGROUPBOX_H

MattyGroupBox.cpp

#include "stdafx.h"
#include "MattyGroupBox.h"
#include "MattyNote.h"


MattyGroupBox::MattyGroupBox()
{
    buildFrame();
}

//void MattyGroupBox::fillFrame(MattyNote & ThisNote)
//{
    //NoteTitleLabel->setText(ThisNote.getTitle());
    //NoteTypeLabel->setText(ThisNote.getType());
    //NoteTextLabel->setText(ThisNote.getText());    
//}

void MattyGroupBox::buildFrame()
{
    // тут очень много того, из-за чего потребовалось наследовать класс
    // добавление элементов Qt

}

MattyGroupBox::~MattyGroupBox()
{
    delete NoteTitleLabel;
    delete NoteTypeLabel;
    delete NoteCrTimeAndDateLabel;
    delete NoteEventTimeAndDateLabel;
    delete NoteTextLabel;
    delete horizontalSpacer_1;
    delete horizontalSpacer_2;
    delete verticalSpacer;
    delete editNoteButton;
    delete deleteNoteButton;
    delete horizontalLayout_1;
    delete horizontalLayout_2;
    delete verticalLayout;
    delete gridLayout;
}

如果取消注释该方法,则会出现错误:

Error   C2511   'void MattyGroupBox::fillFrame(MattyNote &)': overloaded member function not found in 'MattyGroupBox'
Error   C2061   syntax error: identifier 'MattyNote'

MattyNote.h

#ifndef MATTYNOTE_H
#define MATTYNOTE_H

#include "MattyTime.h"

class MattyNote
{
public:
    MattyNote();
    ~MattyNote();
    void setTitle(const QString & Title);
    void setType(const QString & TypeName);
    void setType(int TypeId);
    void setText(const QString & Text);
    void setEventTime(const QString & EventTime); // Warning! Input format must be: 00:00
    void setEventDate(const QString & EventDate); // Warning! Input format must be: 00.00.0000
    QString getTitle();
    QString getType();
    QString getText();
    QString getEventTime(); // Format: 00:00
    QString getEventDate(); // Format: 00.00.0000
    QString getCrTime(); // Format: 00:00
    QString getCrDate(); // Format: 00.00.0000
    int getTypeId();
    TimeAndDate* getEventTimeAndDate(); // Returns a pointer to TimeAndDate structure containing ints
    TimeAndDate* getCrTimeAndDate(); // Returns a pointer to the TimeAndDate structure containing ints
private:
    int NoteTypeId;
    QString NoteTitle;
    QString NoteType;
    QString NoteText;
    QString NoteEventTime; // Format: 00:00
    QString NoteEventDate; // Format: 00.00.0000
    MattyTime* EventTimeAndDate;  // Any unspecified part equals -1
    MattyTime* CrTimeAndDate;  // Automaticly set in constructor of MattyNote
};

#endif // MATTYNOTE_H

MattyNote.cpp

#include "stdafx.h"
#include "MattyNote.h"
#include "Constants.h"
#include "DbManager.h"

MattyNote::MattyNote()
{
    EventTimeAndDate = new MattyTime();
    EventTimeAndDate->setUserTimeAndDateNull();
    CrTimeAndDate = new MattyTime();
    MattyTime::updateCurrTime();
    CrTimeAndDate->UserTimeAndDate = MattyTime::CurrTime;
}

MattyNote::~MattyNote()
{
    delete EventTimeAndDate;
    delete CrTimeAndDate;
}

void MattyNote::setTitle(const QString & Title)
{
    NoteTitle = Title;
}

void MattyNote::setType(const QString & TypeName)
{
    DbManager* MattyNotesDbManager = new DbManager("MattyNotes.sqlite");
    NoteTypeId = MattyNotesDbManager->getTypeId(TypeName);
    NoteType = TypeName;
    delete MattyNotesDbManager;
}

void MattyNote::setType(int TypeId)
{
    DbManager* MattyNotesDbManager = new DbManager("MattyNotes.sqlite");
    NoteType = MattyNotesDbManager->getTypeName(TypeId);
    NoteTypeId = TypeId;
    delete MattyNotesDbManager;
}

void MattyNote::setText(const QString & Text)
{
    NoteText = Text;
}

void MattyNote::setEventTime(const QString & EventTime)
{
    if (EventTime.length() == Constants::TimeQStringLength && EventTime[2] == Constants::TimeSeparator)
    {
        NoteEventTime = EventTime;
        QStringList TimeTemp = EventTime.split(Constants::TimeSeparator);
        EventTimeAndDate->UserTimeAndDate->hour = TimeTemp[0].toInt();
        EventTimeAndDate->UserTimeAndDate->minute = TimeTemp[1].toInt();
        EventTimeAndDate->UserTimeAndDate->second = 0;
    }
}

void MattyNote::setEventDate(const QString & EventDate)
{
    if (EventDate.length() == Constants::DateQStringLength &&
        EventDate[Constants::PositionOfFirstDateSeparator] == Constants::DateSeparator
        && EventDate[Constants::PositionOfSecondDateSeparator] == Constants::DateSeparator)
    {
        NoteEventDate = EventDate;
        QStringList DateTemp = EventDate.split(Constants::DateSeparator);
        EventTimeAndDate->UserTimeAndDate->day = DateTemp[0].toInt();
        EventTimeAndDate->UserTimeAndDate->month = DateTemp[1].toInt();
        EventTimeAndDate->UserTimeAndDate->year = DateTemp[2].toInt();
        EventTimeAndDate->setUserDayOfWeek();
    }
}

QString MattyNote::getTitle()
{
    return NoteTitle;
}

QString MattyNote::getType()
{
    return NoteType;
}

QString MattyNote::getText()
{
    return NoteText;
}

QString MattyNote::getEventTime()
{
    return NoteEventTime;
}

QString MattyNote::getEventDate()
{
    return NoteEventDate;
}

QString MattyNote::getCrTime()
{
    return CrTimeAndDate->PrintUserTime();
}

QString MattyNote::getCrDate()
{
    return CrTimeAndDate->PrintUserDate();
}

int MattyNote::getTypeId()
{
    return NoteTypeId;
}

TimeAndDate * MattyNote::getEventTimeAndDate()
{
    return EventTimeAndDate->UserTimeAndDate;
}

TimeAndDate * MattyNote::getCrTimeAndDate()
{
    return CrTimeAndDate->UserTimeAndDate;
}

stdafx.h 根本不包含标头,Constants.h、DbManager.h、MattyTime.h 和它们的 cpp 也不会发送到任何地方。

实际上,这里可能有什么问题?一般来说,该项目有 10 个头文件和代码文件,如果您需要其他内容,我会发布。

c++
  • 1 个回答
  • 10 Views
Martin Hope
Matty
Asked: 2020-10-09 07:38:31 +0000 UTC

C++ 中的仿函数和运算符

  • 5

我不能完全理解 operator() 在类中是如何工作的,以及原则上它与方法有何不同。

也就是说,有什么区别

class ManOlderThan
{
    int m_age;
public:
    ManOlderThan( int age )
    {
        m_age = age;
    };
    bool operator()( Man &man )
    {
        if( man.GetAge() > m_age ) {
            return true;
        }
        else {
            return false;
        }
    };
};

class ManOlderThan
{
    int m_age;
public:
    ManOlderThan( int age )
    {
        m_age = age;
    };
    bool compare( Man &man )
    {
        if( man.GetAge() > m_age ) {
            return true;
        }
        else {
            return false;
        }
    };
};

那怎么调用呢?或者当只有一种方法时是否需要操作员?或者它们是完全不同的东西?

通常,在这种情况下,运算符在向量和 for_each 和 find_if 的上下文中被考虑

c++
  • 1 个回答
  • 10 Views

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    我看不懂措辞

    • 1 个回答
  • Marko Smith

    请求的模块“del”不提供名为“default”的导出

    • 3 个回答
  • Marko Smith

    "!+tab" 在 HTML 的 vs 代码中不起作用

    • 5 个回答
  • Marko Smith

    我正在尝试解决“猜词”的问题。Python

    • 2 个回答
  • Marko Smith

    可以使用哪些命令将当前指针移动到指定的提交而不更改工作目录中的文件?

    • 1 个回答
  • Marko Smith

    Python解析野莓

    • 1 个回答
  • Marko Smith

    问题:“警告:检查最新版本的 pip 时出错。”

    • 2 个回答
  • Marko Smith

    帮助编写一个用值填充变量的循环。解决这个问题

    • 2 个回答
  • Marko Smith

    尽管依赖数组为空,但在渲染上调用了 2 次 useEffect

    • 2 个回答
  • Marko Smith

    数据不通过 Telegram.WebApp.sendData 发送

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5