Я пытался понять, как перенести данные из одного виджета в другой. У меня есть два виджета, один принимает данные, другой должен их получать и вызывать внутренние функции с полученными данными.
Вот мой код: mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "init.h"
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
void PaymentMethodSwap();
void PaymentTimeSwap();
void updateTotal();
void PushToTable(int index, std::string name, double quantity, double price);
private:
Ui::MainWindow *ui;
public slots:
void receive_data(DataSet&);
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "tips.h"
#include "needs.h"
#include "positionpick.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
updateTotal();
int wdt[4] {25, 135, 65, 50};
auto table = ui->tableWidget;
for (int i =0; i<4; i++){
table->setColumnWidth(i, wdt[i]);
}
connect(ui->soupButton,
&QPushButton::clicked,
this,
[=](){PositionPick *w = new PositionPick; w->setWindowTitle(w->windowTitle()+" - Супы"); w->setCategory(0); w->show();});
connect(ui->secondButton,
&QPushButton::clicked,
this,
[=](){PositionPick *w = new PositionPick; w->setWindowTitle(w->windowTitle()+" - Вторые блюда"); w->setCategory(1); w->show();});
connect(ui->traditionalButton,
&QPushButton::clicked,
this,
[=](){PositionPick *w = new PositionPick; w->setWindowTitle(w->windowTitle()+" - Традиционные блюда"); w->setCategory(2); w->show();});
connect(ui->topDishesButton,
&QPushButton::clicked,
this,
[=](){PositionPick *w = new PositionPick; w->setWindowTitle(w->windowTitle()+" - Блюда месяца"); w->setCategory(3); w->show();});
connect(ui->customButton,
&QPushButton::clicked,
this,
[=](){PositionPick *w = new PositionPick; w->setWindowTitle(w->windowTitle()+" - Свой рецепт"); w->setCategory(4); w->show();});
connect(ui->sweetButton,
&QPushButton::clicked,
this,
[=](){PositionPick *w = new PositionPick; w->setWindowTitle(w->windowTitle()+" - Десерты"); w->setCategory(5); w->show();});
connect(ui->tipsButton,
&QPushButton::clicked,
this,
[=](){Tips *tip = new Tips; tip->show();});
connect(ui->payOptionMethod,
&QPushButton::clicked,
this,
&MainWindow::PaymentMethodSwap);
connect(ui->payOptionTime,
&QPushButton::clicked,
this,
&MainWindow::PaymentTimeSwap);
connect(ui->needsButton,
&QPushButton::clicked,
this,
[=](){Needs *need = new Needs; need->show();});
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::updateTotal(){
ui->totalValue->setText(QString::number(currTransaction.getSum(), 'f', 2));
}
void MainWindow::PushToTable(int index, std::string name, double quantity, double price){
ui->tableWidget->insertRow(ui->tableWidget->rowCount());
ui->tableWidget->setItem(ui->tableWidget->rowCount()-1, 0, new QTableWidgetItem(index));
ui->tableWidget->setItem(ui->tableWidget->rowCount()-1, 1, new QTableWidgetItem(name.c_str()));
ui->tableWidget->setItem(ui->tableWidget->rowCount()-1, 2, new QTableWidgetItem(quantity));
ui->tableWidget->setItem(ui->tableWidget->rowCount()-1, 3, new QTableWidgetItem(price));
}
void MainWindow::PaymentMethodSwap(){
std::string text1 = "Оплата:\nналичными", text2 = "Оплата:\nкартой";
if (ui->payOptionMethod->text() == text1.c_str()) ui->payOptionMethod->setText(text2.c_str());
else ui->payOptionMethod->setText(text1.c_str());
}
void MainWindow::PaymentTimeSwap(){
std::string text1 = "Оплата:\nсразу", text2 = "Оплата:\nпосле";
if (ui->payOptionTime->text() == text1.c_str()) ui->payOptionTime->setText(text2.c_str());
else ui->payOptionTime->setText(text1.c_str());
}
void MainWindow::receive_data(DataSet& data){
std::cout << data.index;
}
позицияpick.h
#ifndef POSITIONPICK_H
#define POSITIONPICK_H
#include <QWidget>
#include <fstream>
#include "init.h"
namespace Ui {
class PositionPick;
}
class PositionPick : public QWidget
{
Q_OBJECT
public:
explicit PositionPick(QWidget *parent = nullptr);
~PositionPick();
void setCategory(int);
void addPositions();
private:
Ui::PositionPick *ui;
std::string category;
signals:
void dataChanged(DataSet&);
};
#endif // POSITIONPICK_H
позицияpick.cpp
#include "positionpick.h"
#include "ui_positionpick.h"
#include "CSVRow.h"
PositionPick::PositionPick(QWidget *parent) :
QWidget(parent),
ui(new Ui::PositionPick)
{
ui->setupUi(this);
addPositions();
connect(ui->resetButton,
&QPushButton::clicked,
this,
[=](){ui->quantity->setValue(1);});
connect(ui->closeButton,
&QPushButton::clicked,
this,
[=](){this->close();});
}
PositionPick::~PositionPick()
{
delete ui;
}
void PositionPick::setCategory(int cat){
switch (cat){
case 0: category = "soups"; break;
case 1: category = "seconds"; break;
case 2: category = "traditional"; break;
case 3: category = "topDishes"; break;
case 4: category = "custom"; break;
case 5: category = "sweets"; break;
default: break;
}
}
void PositionPick::addPositions(){
std::ifstream file(":/foodbase/menu/"+ category + ".csv");
std::vector<std::vector<std::string>> data = readCSV(file);
int index = 0;
std::string btnName;
std::vector<int> {};
for(unsigned long long int i = 1; i < data.size(); i++){
QPushButton *newbutton = new QPushButton;
newbutton->resize(190, 190);
newbutton->setText(data[i][0].c_str());
btnName = ("Button" + std::to_string(index));
newbutton->setObjectName(btnName.c_str());
newbutton->setStyleSheet("QPushButton{\
color: white;\
background-color: #000033;\
border: 1px solid black;\
border-radius: 7px;\
}\
QPushButton:hover{\
background-color: rgb(92, 100, 150);\
}\
QPushButton:pressed{\
background-color:rgb(0, 0, 30);\
border: 3px inset\
}");
newbutton->setParent(ui->ParentWidget);
newbutton->move(5 + i*192, 5+abs(index/3)*192);
connect(ui->ParentWidget->findChild<QPushButton *>(btnName.c_str()),
&QPushButton::clicked,
this,
[=](){currTransaction.addPosition(std::stod(data[i][1]), ui->quantity->text().toDouble()); });
index++;
}
}
Мне нужно перенести данные из выбора позиции (индекс, имя, количество и цена) в главное окно, чтобы вызвать метод PushToTable. Помоги мне, пожалуйста. Заранее спасибо.
Я новичок в qt, поэтому я застрял на сигналах и слотах, я пытался создать сигнал при приеме виджета данных и получении его в виджете главного окна, но это не удалось.
@Botje, я уже пробовал это, я вызвал функцию QObject::connect и передал все параметры, но это не сработало (в моих классах были сигналы: и слоты:)
Отредактируйте свой вопрос, указав, что вы пробовали и какое сообщение об ошибке вы получили.
@Botje только что добавил сигнал и слот, я даже не знаю, что делать дальше... По крайней мере, это ничего не сломало.
Похоже, вам нужно прочитать «Сигналы и слоты». Вы объявляете сигнал PositionPick::dataChanged
, но никогда emit
его не делаете. Точно так же вы никогда не connect
подаете этот сигнал в слот MainWindow::receive_data
(при условии, что вы это пытаетесь сделать).
Пожалуйста, создайте минимальный воспроизводимый пример, т. е. удалите весь код, который не является строго необходимым для демонстрации вашей проблемы.
Я не знаю, что это за класс DataSet
, поэтому я просто покажу вам, как генерировать все переменные отдельно.
Для начала добавьте сигнал в PositionPick
:
signals:
void addToTransaction(int index, QString name, double quantity, double price);
Затем измените addPositions
следующим образом:
void PositionPick::addPositions(){
std::ifstream file(":/foodbase/menu/"+ category + ".csv");
std::vector<std::vector<std::string>> data = readCSV(file);
int index = 0;
for(unsigned long long int i = 1; i < data.size(); i++){
QPushButton *newbutton = new QPushButton;
newbutton->resize(190, 190);
QString name = QString::fromStdString(data[i][0]); // this is how you convert std::string to QString
newbutton->setText(name);
newbutton->setObjectName(QString("Button%1").arg(index));
newbutton->setStyleSheet(/*elided for brevity*/);
newbutton->setParent(ui->ParentWidget);
newbutton->move(5 + i*192, 5+abs(index/3)*192);
double unitPrice = /* fill in. data[i][2] maybe? */;
connect(newButton,
&QPushButton::clicked,
this,
[=](){ // This lambda captures the current value of index, name and unitPrice.
double quantity = ui->quantity->value();
emit addToTransaction(index, name, quantity, quantity * unitPrice);
});
index++;
}
}
Затем подключите виджет к своему окну, вызвав
QObject::connect(w, &PositionPick::addToTransaction, &MainWindow::PushToTable);
сразу после создания объекта PositionPick
.
Наконец, сделайте MainWindow::addToTransaction
прорезь.
Еще несколько замечаний: посмотрите, сможете ли вы сделать ui->ParentWidget
QGridLayout
или что-то подобное, чтобы вам не приходилось самостоятельно рассчитывать позиции. Напишите осмысленные именованные вспомогательные методы вместо копирования одной и той же строки 7 раз. И прочитайте документацию по QString. Он присутствует повсюду в Qt и имеет множество служебных функций, особенно для преобразования в другие типы строк и обратно.
Добавьте блок
signals:
в PositionPick и изменитеaddPositions
, чтобы он излучал этот сигнал. Измените MainWindow, чтобы подключить слот к сигналу PositionPick. Покажите нам, что вы пробовали.