Просмотр сообщений
|
Страниц: [1] 2 3
|
1
|
Qt / Вопросы новичков / Re: Статическая сборка 5.14 , сохранение юникода в файле
|
: Июнь 25, 2020, 12:54
|
Наверное вы добавили библиотеки только тех объектов, которые были использованы в программе. У меня так много всего, что придется долго отбирать, что использовано а что нет. В соответствии с LGPL лицензией, я, кажется, должен буду добавить к демке не только библиотеки, но и исходники Qt. Мне бы хотелось запихнуть все в один исполняемый файл. Демка не для всеобщего обозрения, а будет высылаться по запросу, в ответ на проявленный интерес. Так что вопросы о нарушении лицензии в данном случае вряд ли уместны... Демка абсолютно бесплатна, а платной версии программы не существует и вряд ли она появится раньше, чем будет куплена коммерческая версия Qt.
Нет не только, я ничего не менял в добавляемых модулях, потому-что боялся, что что-нибудь не будет работать, а статическая сборка создается мягко говоря не быстро... Там было немало лишнего, что по идее можно было убрать, но как я ранее объяснил не стал этого делать, для меня не критично было сколько весит экзэшник 15 Мб, или 9 Мб... Единственное добавил модуль ms-sql, так-как мне нужен был функционал работающий с ms sql server.
|
|
|
2
|
Qt / Вопросы новичков / Re: Статическая сборка 5.14 , сохранение юникода в файле
|
: Июнь 25, 2020, 12:48
|
Мне просто интересно - зачем всем именно 1 исполняемый файл? Не проще ли сделасть инсталлятор - он заодно и избавит от вопросов "где та программа, которую я зачем то ставил на прошлой неделе?"
Это риторический вопрос, у каждого свои причины, так же можно спросить, зачем кому-то нужны портабл версии ПО?
|
|
|
3
|
Qt / Вопросы новичков / Re: Статическая сборка 5.14 , сохранение юникода в файле
|
: Июнь 24, 2020, 10:57
|
Да, так можно. Я так делал 3 года назад с какой-то из 5-х версий, но получится пакет размером 1.5 гиг. А при статической компиляции (правда, на 4-ке) получился экзешник 20 мегабайт со всеми нужными либами внутри + несколько мелких файлов. У меня программа скомпилированная на Qt 5.3 получилась 15 Мб (программа содержит разные виджеты, диалоговые окна, есть справка, работает с БД MSSQL и большими текстовыми файлами, и т.д.)
|
|
|
7
|
Qt / Вопросы новичков / Re: Как проверить, пуста ли EditLine?
|
: Июнь 13, 2020, 15:39
|
И что этот рабочий пример делает? Насколько я понял, добавляет виджет, но судя по h файлу, виджет мышки которая может удалять. Рабочий пример: ....
Мне просто нужно, когда пользователь в первый раз нажимал на это поле с него стиралось фраза "Введите название". Естественно. я надеялся, что в момент нажатия на поле ввода, посылается сигнал. что поле стало активным, что с ним начали работать или что то в этом духе, чтобы потом слотом сделать settext(""); и всё. Не понимаю, что даёт переопределение mouseЕvent'a. Если создать два файла lineed.h и main.cpp и добавить их в проект, удалив при этом лишние файлы (если они были созданы), то сразу станет понятно, что этот пример делает. Я не поленился этот пример написать, а ты не поленись сделать пару раз копипаст. Код этого примера избыточен, main можно так написать: main.cpp:C++ (Qt) #include <QtWidgets> #include "lineed.h" int main(int argc, char** argv) { QApplication app(argc, argv); LineEd LnEd; LnEd.show(); return app.exec(); }
А чтобы не удалялось всё, что написано в поле QLineEdit, можно в методе mousePressEvent() задать дополнительное условие: lineed.h:C++ (Qt) #ifndef LINEED_H #define LINEED_H #include <QtWidgets> class LineEd : public QLineEdit { protected: virtual void mousePressEvent(QMouseEvent*) { if(text() == "My Text") clear(); } public: LineEd(QWidget *wgt = 0) : QLineEdit(wgt) {} }; #endif // LINEED_H
P.S.: поясню, в файле lineed.h происходит создание класса LineEd, наследуемого от QLineEdit. Это необходимо для того, чтобы переопределить метод mousePressEvent(), для работы с событиями мыши, а именно "клика" по полю QLineEdit. "My Text" - это текст, который будет удаляться из поля LineEd при клике по полю мышкой (другой текст удаляться не будет). Думаю подробно объяснил. А, вообще, по-моему, это геморрой так программировать, не зная азы C++, но за настойчивость и терпение респект
|
|
|
8
|
Qt / Вопросы новичков / Re: QTableWidget - вопрос по insert, remove rows
|
: Июнь 09, 2020, 12:31
|
Да, там все реализовано, с параметрами только разобраться надо
((QAbstractItemModel*)tbl_channels)->removeRows(RowNums);
((QAbstractItemModel*)tbl_channels)->insertRows(Count, NewRowCount - Count);
Изначально вопрос стоял про QTableWidget, при чем тут концепция "модель-представление"? В QTableWidget есть два слота о которых я выше писал. С их помощью можно реализовать приведенный вами код. Единственное нужны будут дополнительные циклы по вектору (для удаления/вставки нужных строк).
|
|
|
10
|
Qt / Вопросы новичков / Re: Combobox и БД
|
: Июнь 07, 2020, 14:20
|
Со старого проекта дернул подключение к БД и накидал вариант решения задачи с использованием QMultiHash ("Multi" на случай, если значения поля Name в таблице повторяются). С помощью QtDesigner создал виджет и "кинул" на него QComboBox и QPushButton. P.S.: Единственное не сделал проверку на повторяющиеся значения. Надо будет использовать метод QHash::values(), который возвращают QList(). И уже с этим списком работать... В данном случае будет возвращено только одно значение Id (последнее в QMultiHash). Если точно повторений в таблице нет, то достаточно метода QHash::value(). И совет от новичка в Qt новичку: старайся почаще заглядывать в справку, сначала будет сложно разобраться, придется все-равно часто обращаться к интернету, но со временем станет легче разбираться с материалом и это скажется на быстроте кодинга и эффективности. И не забывай смотреть методы родителей класса, там много интересного И еще, советую простые окна (формы) создавать вручную (без QtDesigner) так зачастую проще и меньше лишнего кода. Наследуешься от QWidget, создаешь нужные элементы управления, создаешь нужный Layout, добавляешь в него эти элементы управления и устанавливаешь Layout на данный виджет. Спасибо за помощь, но мне все-таки не нравится вариант с хранением пары <QString, int> в каком-либо контейнере. Это требует написания лишнего кода, например, как вы уже отметили, в случае, если значения могут повторяться. Я воспользовался вариантом, который написал demal: model = new QSqlQueryModel(); model->setQuery(QString("SELECT -1 as Id, '(Выберите категорию)' as Name UNION SELECT Id, Name FROM Cat WHERE Cat.Art=%1").arg(articleId)); ui->chooseCategory->setModel(model); ui->chooseCategory->setModelColumn(1);//В комбобоксе отображается содержимое столбца Name //Если нужно получить Id: int id = model->record(ui->chooseCategory->currentIndex()).value(0).toInt();
Все просто и лаконично, как мне кажется. К БД обращаемся всего один раз) Пожалуйста. Если вариант demal подходит больше и код меньше, то он лучший. Просто, как правило, технология "модель - представление" используется для "больших" данных, а в вашем случае, как я понял, их немного (раз помещаете результат запроса в QComboBox). Но самое главное чтобы код корректно и быстро работал, и был достаточно лаконичен
|
|
|
11
|
Qt / Вопросы новичков / Re: Combobox и БД
|
: Июнь 07, 2020, 08:23
|
Со старого проекта дернул подключение к БД и накидал вариант решения задачи с использованием QMultiHash ("Multi" на случай, если значения поля Name в таблице повторяются). С помощью QtDesigner создал виджет и "кинул" на него QComboBox и QPushButton. widget.h:C++ (Qt) #ifndef WIDGET_H #define WIDGET_H #include <QWidget> #include <QMultiHash> class QSqlQuery; namespace Ui { class Widget; } class Widget : public QWidget { Q_OBJECT public: bool createConnection(); explicit Widget(QWidget *parent = 0); ~Widget(); private slots: void on_pushButton_clicked(); private: Ui::Widget *ui; QSqlQuery *query; QMultiHash<QString, int> *queryHash; }; #endif // WIDGET_H widget.cpp:C++ (Qt) #include <QtWidgets> #include <QSqlDatabase> #include <QSqlError> #include <QSqlQuery> #include <QMultiHash> #include "widget.h" #include "ui_widget.h" Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget) { ui->setupUi(this); if(!createConnection()) { // connection don't create return; } query = new QSqlQuery; QString strQuery = "SELECT Id, Art, Name " "FROM MyTable "; query->setForwardOnly(true); // faster if(!query->exec(strQuery)) { QMessageBox::critical(this, "Error", QString("Query error") + query->lastError().driverText() + "; " + query->lastError().databaseText()); return; } queryHash = new QMultiHash<QString, int>(); // insert items to queryHash and comboBox from field "Name" while(query->next()) { queryHash->insert(query->value("Name").toString(), query->value("Id").toInt()); ui->comboBox->addItem(QString(query->value("Name").toString())); } } bool Widget::createConnection() { // create connection to DB QSqlDatabase db = QSqlDatabase::addDatabase("QODBC3"); QString host = "SERVER\\SQL2008SRV"; QString dataBase= "MyBase"; QString userName = "sa"; QString password = "password"; db.setDatabaseName(QString("Driver={SQL Server};" "Server=%1;Database=%2; Persist Security Info=true;" "uid=%3;pwd=%4").arg(host).arg(dataBase).arg(userName).arg(password)); if(!db.open()) { QMessageBox::critical(this, "Error", QString("Connection error")); return false; } return true; } void Widget::on_pushButton_clicked() { if(queryHash->contains(ui->comboBox->currentText())) { QMessageBox::information(this, "Value", QString("Id = <b>" + QString().setNum(queryHash->value(ui->comboBox->currentText())) + "</b>") ); } } Widget::~Widget() { delete ui; delete query; delete queryHash; } main.cpp:C++ (Qt) #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) { QApplication a(argc, argv); Widget w; w.show(); return a.exec(); }
Нужный результат выдается в слоте on_pushButton_clicked() при сигнале clicked() кнопки pushButton. C++ (Qt) void Widget::on_pushButton_clicked() { if(queryHash->contains(ui->comboBox->currentText())) { QMessageBox::information(this, "Value", QString("Id = <b>" + QString().setNum(queryHash->value(ui->comboBox->currentText())) + "</b>") ); } }
P.S.: Единственное не сделал проверку на повторяющиеся значения. Надо будет использовать метод QHash::values(), который возвращают QList(). И уже с этим списком работать... В данном случае будет возвращено только одно значение Id (последнее в QMultiHash). Если точно повторений в таблице нет, то достаточно метода QHash::value(). И совет от новичка в Qt новичку: старайся почаще заглядывать в справку, сначала будет сложно разобраться, придется все-равно часто обращаться к интернету, но со временем станет легче разбираться с материалом и это скажется на быстроте кодинга и эффективности. И не забывай смотреть методы родителей класса, там много интересного И еще, советую простые окна (формы) создавать вручную (без QtDesigner) так зачастую проще и меньше лишнего кода. Наследуешься от QWidget, создаешь нужные элементы управления, создаешь нужный Layout, добавляешь в него эти элементы управления и устанавливаешь Layout на данный виджет.
|
|
|
12
|
Qt / Вопросы новичков / Re: Combobox и БД
|
: Июнь 07, 2020, 07:34
|
Доброго времени суток, уважаемые форумчане. Qt начал заниматься недавно. Разрабатываю приложение для ведения расходов. В моем приложении используется БД SQLITE. В ней есть следующая таблица: Это Названия категорий расходов. Id - внешний ключ. На графическом интерфейсе у меня есть Combobox. В него я заношу имена категорий таким образом: 1) Создаю объект QSqlQuery и выполняю запрос в БД на выборку всех имен продуктов. 2) Далее с помощью addItem добавляю это в Combobox. Далее, в некотором месте программы я хочу получить Id категории в соответствии с тем, что в данный момент выбрано в combobox'е. И вот тут из-за того, что в Qt я новичок, я не совсем понимаю, как грамотно это сделать. В голову приходят следующие идеи: 1) Выполнять SQL-запрос на поиск Id категории по ее имени. 2) Либо где-то в таблице хранить map<Name,Id>. И в нужный момент получить нужный Id по имени. Очевидно, что оба эти подхода плохие, хочется какого-то более элегантного решения. Т.е., грубо говоря, чтобы я мог написать ui->combobox->currentText() и получить не имя категории, а именно ее Id. Надеюсь на вашу помощь. Постоянно выполнять из программы SQL-запросы, это не очень хорошая идея, тем более всё можно реализовать только средствами Qt (выполнив прежде один запрос к БД). Я бы работал не с моделью в данном случае (если база небольшая) а с QSqlQuery. Выполняешь запрос с необходимыми для задачи полями, "помещаешь" его в объект QSqlQuery. Метод next() для итерирования (прохода) по всем строкам запроса и методы: value(int), value(const QString &), для выбора нужного поля в таблице БД. Результат запроса можно поместить в QMultiHash, например (на случай совпадений в базе значений поля Name). И далее работать с хэш-таблицей...
|
|
|
13
|
Qt / Вопросы новичков / Re: заполнить таблицу ответом на sql-запрос
|
: Май 30, 2020, 15:12
|
Это если связанные таблицы по ключу, а если у него более сложный запрос, то не получится использовать QSqlRelationalTableModel.
Ну всегда можно связать таблицы через другие, а если нельзя, то в этом нет смысла, по крайней мере если база спроектирована грамотно...
|
|
|
14
|
Qt / Вопросы новичков / Re: Как проверить, пуста ли EditLine?
|
: Май 30, 2020, 05:02
|
А вообще, в случае. если у меня число в поле по умолчанию есть, а я хочу, чтобы при наведении на поле и нажатию по нему, текст исчезал, это какой сигнал?(понятно, что после этого, можно просто ui->settext(""); сделать). Проверка нужна чтобы после этого, пользователь может ввести в поле, что нибудь ещё, передумать, стереть и написать ещё раз.
Это не сигнал, а слот. Сигнал просто сигнализирует о чем-то, а слот уже производит какое-то действие.Слот - void QLineEdit::clear(), а подходящего сигнала для QLineEdit нет. Поэтому самое простое перегрузить метод события. Помогут классы событий. Например класс события мыши. Можно перегрузить метод mousePressEvent(QMouseEvent *e) - https://doc.qt.io/qt-5/qlineedit.html#mousePressEvent. Либо focusInEvent(QFocusEvent *e) - https://doc.qt.io/qt-5/qlineedit.html#focusInEvent, но в этом случае фокус элементом может быть получен, не только по нажатию мыши. Рабочий пример: lineed.h:C++ (Qt) #ifndef LINEED_H #define LINEED_H #include <QtWidgets> class LineEd : public QLineEdit { protected: virtual void mousePressEvent(QMouseEvent*) { clear(); } public: LineEd(QWidget *wgt = 0) : QLineEdit(wgt) {} }; #endif // LINEED_H main.cpp:C++ (Qt) #include <QtWidgets> #include "lineed.h" int main(int argc, char** argv) { QApplication app(argc, argv); QWidget wgt; LineEd *LnEd = new LineEd; QVBoxLayout* vLayout = new QVBoxLayout; vLayout->addWidget(LnEd); wgt.setLayout(vLayout); wgt.show(); return app.exec(); }
|
|
|
|
|