LINUX.ORG.RU

Много файловый проект C++ Qt

 ,


1

3

Доброе время суток лорчане. Раньше программировал под дотнет, теперь как будто в новом мире оказался, извиняюсь если где то очень грубо ошибаюсь.
Привел код к следующими виду.
в sql_query.h

#ifndef SQL_QUERY_H
#define SQL_QUERY_H
 
#include <QMainWindow>
#include <QtSql>
 
#include <string>
using namespace std;
 
 
class sql_query
{
public:
    sql_query(string command);
    QSqlQueryModel * modal;
    QSqlQuery* query;
    string message;
};
 
#endif // SQL_QUERY_H
В sql_query.cpp
#include <string>
using namespace std;
 
 
 
sql_query::sql_query(string command)
{
    public:
    QSqlQueryModel * modal;
    QSqlQuery* query;
    string message;
    /* Загружается данный из БД в tableView */{
        QSqlDatabase sdb = QSqlDatabase::addDatabase("QSQLITE");
         sdb.setDatabaseName("/home/localadmin/project/Inventory_Management/DB_IM.db");
         sdb.setHostName("localhost");
         modal = new QSqlQueryModel();
         query = new QSqlQuery();
         if(!sdb.open()){
             message = "Подключение к базе не удалось";
         }
 
           else
           {
             query->prepare(command);
             query->exec();
             //modal->setQuery(*query);
             sdb.close();
     }
    }
 
}
В cpp (directory_firma.cpp) файле в котором я обращаюсь к классу.
#include "directory_firma.h"
#include "ui_directory_firma.h"
#include "qsqldatabase.h"
#include "qsql.h"
#include "qsqlquery.h"
#include "qsqlquerymodel.h"
#include "qdebug.h"
#include <sql_query.h>
 
directory_firma::directory_firma(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::directory_firma)
{
 
    ui->setupUi(this);
    sql_query("select directory_firma_name FROM directory_firma");
    ui->tableView->setModel(*modal);
    modal->setQuery(*query);
    qDebug() <<(modal->rowCount());
 
 
}
 
directory_firma::~directory_firma()
{
    delete ui;
}
 
}

Компилятор ругается:


../Inventory_Management/directory_firma.cpp:17:30: error: ‘modal’ was not declared in this scope
ui->tableView->setModel(*modal);
^~~~~

../Inventory_Management/directory_firma.cpp:18:22: error: ‘query’ was not declared in this scope
modal->setQuery(*query);
^~~~~
Но я же подключи заголовочный файл sql_query.h в directory_firma.cpp
Описал в заголовочном файле sql_query.h переменные и (правда привел их к типу паблик(позже буду разбираться с «полями»)) и функцию.
И реализовал функцию в sql_query.cpp.
Подскажите пожалуйста, что я делаю не так?



Последнее исправление: farex (всего исправлений: 1)

Раньше программировал под дотнет, теперь как будто в новом мире оказался, извиняюсь если где то очень грубо ошибаюсь.

Вы пытаетесь постичь C++ и Qt с наскока, так дело не пойдёт. У вас действительно немножечко ада в представленном вами коде.

Расслабьтесь и прочитайте вечерком пару глав книжки какого-нибудь там Стивена Праты или Бьёрна Страуструпа. Это если дело не горит. А если горит, передайте проект компетентному C++/Qt программисту.

EXL ★★★★★
()
sql_query myQuery("select directory_firma_name FROM directory_firma");
ui->tableView->setModel(*myQuery->modal);
modal->setQuery(*myQuery->query);
qDebug() << (myQuery->modal->rowCount());

Если Вы ничего не понимаете в этих поправках, то удваиваю товарища EXL.

Northsoft ★★
()
Ответ на: комментарий от Northsoft
18: ошибка: base operand of ‘->’ has non-pointer type ‘sql_query’
     ui->tableView->setModel(*myQuery->modal);

^~ Свою ошибку вроде понял (прошу поправить если не прав): Я не создал экзепляр класса.
Но компилятор все равно ругается.

farex
() автор топика
Ответ на: комментарий от EXL

Проект мне не горит, да и не проект это... Переписываю уже реализованную программу на дотнете. с++ изучаю постепенно на примерах.
Посоветуйте пожалуйста хорошую литературу по С++ и QT (именно в этой связке)

farex
() автор топика
Ответ на: комментарий от farex

Я начинал изучение с книги С. Прата. «Язык программирования C++. Лекции и упражнения 6 издание». Отличная книга.
Еще Скотта Майерса книги мне понравились.
Ну а далее уже нужно смотреть справочную документацию к языку и примеры:
http://en.cppreference.com/w/cpp
http://www.cplusplus.com/reference/
По поводу Qt книгу уже назвали, ну и конечно смотреть документацию и примеры:
http://doc.qt.io/qt-5/index.html

rumgot ★★★★★
()

А зачем смешивать STL и Qt? Вместо std::string используй QString. Всё равно оно неявно преобразуется

XMs ★★★★★
()
Ответ на: комментарий от EXL

Прочитал статью https://ru.opensuse.org/QT_и_Базы_данных
Понял что был не прав.

QSqlTableModel model;
model.setTable("employee");
model.select();
 
QTableView view;
view.setModel(&model);
view.show();
Но все же, никак не могу понять как разбить например вышеприведенный код на файлы заголовка, исходника, и исходника который вызывает этот класс. т.е. в файлы sql_query.h sql_query.cpp mywindow.cpp В C# я привык создавать класс так сказать конструктор sql запросов, то есть передаешь экземпляру класса запрос, параметры, а он тебе возвращает готовый DataTable.

farex
() автор топика
Ответ на: комментарий от farex

Я не создал экзепляр класса
error: ‘modal’ was not declared in this scope
error: ‘query’ was not declared in this scope

Нет. Если бы ты не создал экземпляр класса, у тебя бы оно скомпилировалось, а потом упало. Компилятор говорит, что идентификаторы «modal» и «query» не были объявлены в текущей области видимости.


base operand of ‘->’ has non-pointer type ‘sql_query’

Думаю, Northsoft опечатался, там не должно быть оператора разыменования (звёздочки), а вместо оператора -> должна быть точка. Либо, как вариант, вместо разыменования должно было быть взятие адреса (&). Я не помню, можно ли эти классы размещать на стеке, может быть, подразумевалось размещение в куче

XMs ★★★★★
()
Ответ на: комментарий от farex

Но все же, никак не могу понять как разбить например вышеприведенный код на файлы заголовка, исходника, и исходника который вызывает этот класс

Для начала: для чего тебе нужен целый класс sql_query? Чем он (для тебя с точки зрения архитектуры твоего приложения) отличается от того же QSqlQuery? По-моему тут, для того, что указано, достаточно одного main.cpp, без собственных классов.

Хорошая практика для самопроверки: перед объявлением класса давать краткую сводку того, чем, по твоему мнению, он должен заниматься. Если в процессе дальнейшего кодинга начинаешь замечать, что отходишь от этой сводки, либо бьёшь себя по рукам, либо думаешь, почему возникла такая необходимость и, по результатам дум, пересматриваешь архитектуру

XMs ★★★★★
()

Твой код ужасен, зачем указатели дублируются, зачем вообще создаешь через new эти объекты? А где delete? У тебя сисярп головного мозга :)

Qt как раз позволяет создавать объекты, а потом их деструкторы автоматом чистят. Поменьше используй new, а там где использовал - каждому new должен соответствовать delete. Типа alloc + free.

I-Love-Microsoft ★★★★★
()
Ответ на: комментарий от XMs

В данном контексте согласен с замечанием, но всё равно похоже на вброс )

UVV ★★★★★
()
Ответ на: комментарий от XMs

В C# я привык создавать класс так сказать конструктор sql запросов, то есть передаешь экземпляру класса запрос, параметры, а он тебе возвращает готовый DataTable и.т.п.

farex
() автор топика
Ответ на: комментарий от farex

Из официальных доков:

QSqlQuery query("SELECT country FROM artist");
while (query.next()) {
    QString country = query.value(0).toString();
    doSomething(country);
}

По-моему, это более чем подходит под твоё описание

XMs ★★★★★
()
Ответ на: комментарий от CrossFire

Ага, спасибо. Подредактировал. А кроме Макса Шлее на русском ничего не выходило ещё? А то тут слабо как-то обновляется: https://wiki.qt.io/Books

EXL ★★★★★
()

в sql_query.h

...

#include <string>
using namespace std;

...

В заголовочном файле так делать - очень дурной тон. Когда ты так делаешь, любой пользователь твоего заголовочного файла получает в «подарок» using namespace std даже не подозревая об этом (потому что #include «bla-bla-bla» в начале файла означает просто команду препроцессору подставить в эту строчку содержание файла «bla-bla-bla»).

asaw ★★★★★
()
Ответ на: комментарий от I-Love-Microsoft

Да кто вообще помнит про ваш quick time?

Чей наш?

Это как удивляться почему побили за древний индийский символ, перепутав с немецким ;)

А почему нужно удивляться?

andreyu ★★★★★
()

Прочитай вначале K&R (там нечего читать, просто просмотри, указатели осиль только).

Потом внимательно смотри на RAII, Copy constructors, Move semantics.

Потом сюда http://en.cppreference.com/w/cpp/language в поисках непонятного.

Темплейты можно долго осиливать, но без них таки можно жить (плохо). Без raii и понимания че там с памятью - нельзя.

А, еще книжки Мейерса норм. Это, фактически, сборники частых ошибок, многотекста там нет.

Kuzy ★★★
()
Последнее исправление: Kuzy (всего исправлений: 1)
Ответ на: комментарий от Kuzy

Вот за это огромное спасибо.
Сам синтаксис С++ мне мне понятен... а вот указатели это для меня что-то новое. На сишарп сижу уже давно и видимо при изучении его недопонял про указатели, либо просто забыл про них, но за 8 лет. не разу не использовал.

farex
() автор топика
Ответ на: комментарий от x905

(В подлиннике)

Да, опасайтесь подделок — там толпа бутлеггеров комментируют и перевирают капитана очевидность :)

slackwarrior ★★★★★
()
Ответ на: комментарий от farex

а вот указатели это для меня что-то новое. На сишарп сижу уже давно и видимо при изучении его недопонял про указатели

не разу не использовал.

Да не новое. И использовал все время :) В твоем сишарпе все классы «ссылочные типы». Знаешь почему? Прост ручной секас с указателями где-то под капотом: «So we herd you dislike pointers, so we placed pointers behind your so-called „reference types“, so you could proceed dislike pointers while you think like „What pointers?“

slackwarrior ★★★★★
()
 sql_query::sql_query(string command) 
{ 
    public: 
    QSqlQueryModel * modal; 
    QSqlQuery* query; 
    string message;

Это где такому учат? Не стреляй себе в лицо из пулемета,останься на шарпе

jo_b1ack ★★★★★
()
Ответ на: комментарий от EXL

Всем спасибо за ответы.

Воспользовался вашим советом, остановился и все пересмотрел и обдумал.
Да в голове была каша когда я это писал.
Не могли бы вы посмотреть на код который я написал ниже и указать на новые ошибки.

Проект имеет следующие файлы:
Заголовочные:
connection_db.h (заголовочный файл созданный мной)
mainwindow.h (тут все по умолчанию)
Исходные файлы: connection_db.cpp (исходный файл созданный мной)
main.cpp (тут все по умолчанию)
mainwindow.cpp

connection_db.h

#ifndef CONNECTION_DB_H
#define CONNECTION_DB_H
#include "QtSql"
#include "QString"

class connection_db
{
public:
    connection_db();
    QSqlDatabase sdb = QSqlDatabase::addDatabase("QSQLITE");
    int open();
    int close();
    QString patch_to_db;
};
#endif // CONNECTION_DB_H

connection_db.h
#include "connection_db.h"
#include "QtSql"

connection_db::connection_db()
{
}
connection_db::open()
{
    sdb.setDatabaseName(patch_to_db);
    sdb.open();
    return 1;
}
connection_db::close()
{
    sdb.close();
    return 0;
}

И mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "connection_db.h"
#include "QMessageBox"

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

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

void MainWindow::on_pushButton_clicked()
{
    connection_db conn_db;
    conn_db.patch_to_db = "C:\\Project\\test_sql\\test.db";
    if(conn_db.open() == 1){
        QSqlQueryModel* model;
        model = new QSqlQueryModel();
        model->setQuery("SELECT * FROM table1");
        ui->tableView->setModel(model);
        conn_db.close();
        // qDebug() << query->lastError();
    }
    else if(conn_db.open() == 0){
       QMessageBox message_box;
       message_box.setText("Connection not open");
       message_box.exec();
    }
}

farex
() автор топика
Последнее исправление: farex (всего исправлений: 1)
Ответ на: Всем спасибо за ответы. от farex

Класс connection_db излишен, это по сути обёртка над QSqlDatabase, которая почти ничего сама не делает.

Если на какое-то время забыть про это, то появляются такие мысли:

  1. Размещение члена класса в public — нарушение принципа инкапсуляции. В таких случаях члены класса прячутся в private/protected, а для доступа к ним делаются сеттеры и геттеры.
  2. Инициализация в хедере — не знаю, я бы перенёс в cpp-файл от греха подальше, куда-нибудь в конструктор.
  3. Совершенно непонятно, почему функции open() и close() возвращают int вместо какого-нибудь bool для open() и void для close(), и тем более непонятно, почему первая возвращает 1 (true), а вторая — 0 (false) для одинаково успешного завершения. В функции open() просто напрашивается что-то типа return sdb.open();

Остальное (код кнопки) пока можно опустить

XMs ★★★★★
()
Ответ на: комментарий от farex

Было бы неплохо посмотреть, на что именно ругался компилятор

XMs ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.