C++ Qt:如何将输入值从点击按钮传递到paintGL()函数
我正在使用QT开发抵押贷款计算器。 当用户单击按钮时,“on_button_clicked()”函数将获得输入 问题是,我不知道如何将输入从“on_putton_clicked()”传递到“paintGL()”函数以用于绘图 我最后的办法是使用全局变量来解决这个问题,但我真的想避免这样的事情……因此,如果有人能用更好的方法来启发,那将是非常受欢迎的 我的代码如下: 主窗口C++ Qt:如何将输入值从点击按钮传递到paintGL()函数,c++,qt,C++,Qt,我正在使用QT开发抵押贷款计算器。 当用户单击按钮时,“on_button_clicked()”函数将获得输入 问题是,我不知道如何将输入从“on_putton_clicked()”传递到“paintGL()”函数以用于绘图 我最后的办法是使用全局变量来解决这个问题,但我真的想避免这样的事情……因此,如果有人能用更好的方法来启发,那将是非常受欢迎的 我的代码如下: 主窗口 #ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainW
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "ui_mainwindow.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
template <class T>
T inputcheck(QLineEdit *input, T output);
//friend class GLwidget;
double loan;
int maturity;
double rate1;
double rate2;
double rate3;
int period2;
int period3;
private slots:
void on_pushButton_Calculate_clicked();
void on_pushButton_Quit_clicked();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
signals:
void MySignal(MyStruct*);
\ifndef主窗口
#定义主窗口
#包括
#包括“ui_main window.h”
名称空间用户界面{
类主窗口;
}
类主窗口:公共QMainWindow
{
Q_对象
公众:
显式主窗口(QWidget*parent=0);
~main窗口();
样板
T输入检查(QLineEdit*输入,T输出);
//朋友类小部件;
双重贷款;
智力成熟度;
双费率1;
双费率2;
双费率3;
int周期2;
int周期3;
专用插槽:
单击按钮计算时无效();
单击按钮退出时无效();
私人:
Ui::MainWindow*Ui;
};
#endif//main窗口
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QCoreApplication>
#include <QDesktopWidget>
#include "glwidget.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
template <class T>
T MainWindow::inputcheck(QLineEdit *input, T output)
{
bool ok;
output = input->text().toDouble(&ok);
if(TRUE && output > 0)
{
return output;
}
else
{
input->setText("ERR");
return 0;
}
}
void MainWindow::on_pushButton_Calculate_clicked()
{
// getting inputs()
loan = inputcheck(ui->lineEdit_loan, loan);
maturity = inputcheck(ui->lineEdit_maturity, maturity);
rate1 = inputcheck(ui->lineEdit_rate1, rate1);
rate2 = inputcheck(ui->lineEdit_rate2, rate2);
rate3 = inputcheck(ui->lineEdit_rate3, rate3);
period2 = inputcheck(ui->lineEdit_period2, period2);
period3 = inputcheck(ui->lineEdit_period3, period3);
printf("loan:%f, maturity:%d,rate1:%f,rate2:%f,rate3:%f, period2:%d, period3:%d\n", loan, maturity, rate1, rate2, rate3, period2, period3);
}
void MainWindow::on_pushButton_Quit_clicked()
{
QCoreApplication::quit();
}
#包括“mainwindow.h”
#包括“ui_main window.h”
#包括
#包括
#包括“glwidget.h”
主窗口::主窗口(QWidget*父窗口):
QMainWindow(父级),
用户界面(新用户界面::主窗口)
{
用户界面->设置用户界面(此);
}
MainWindow::~MainWindow()
{
删除用户界面;
}
样板
T MainWindow::inputcheck(QLineEdit*输入,T输出)
{
布尔ok;
输出=输入->文本();
if(TRUE&&output>0)
{
返回输出;
}
其他的
{
输入->设置文本(“错误”);
返回0;
}
}
void主窗口::在按钮上单击计算()
{
//获取输入()
loan=输入检查(ui->lineEdit\u loan,loan);
到期日=输入检查(ui->lineEdit\u到期日,到期日);
rate1=输入检查(ui->lineEdit\u rate1,rate1);
rate2=输入检查(ui->lineEdit_rate2,rate2);
rate3=输入检查(ui->lineEdit_rate3,rate3);
period2=输入检查(ui->lineEdit\u period2,period2);
period3=输入检查(ui->lineEdit\u period3,period3);
printf(“贷款:%f,到期日:%d,利率1:%f,利率2:%f,利率3:%f,周期2:%d,周期3:%d\n”,贷款,到期日,利率1,利率2,利率3,周期2,周期3);
}
void主窗口::按按钮退出
{
QCoreApplication::quit();
}
glwidget.h
#ifndef GLWIDGET_H
#define GLWIDGET_H
#include <QObject>
#include <QGLWidget>
class calculation;
class GLwidget : public QGLWidget
{
Q_OBJECT
public:
explicit GLwidget(QWidget *parent = 0);
void initializeGL();
void paintGL();
void resizeGL(int width, int height);
private:
};
#endif // GLWIDGET_H
\ifndef GLWIDGET\u H
#定义glu\H
#包括
#包括
班级计算;
类GLwidget:publicqglwidget
{
Q_对象
公众:
显式GLwidget(QWidget*parent=0);
void initializeGL();
void paintGL();
空隙大小(内部宽度、内部高度);
私人:
};
#endif//glu\H
glwidget.cpp
#include "glwidget.h"
#include <gl/GL.h>
GLwidget::GLwidget(QWidget *parent):QGLWidget(parent)
{
}
void GLwidget::initializeGL()
{
}
void GLwidget::paintGL()
{
**// I need the inputs to be here!!**
}
void GLwidget::resizeGL(int width, int height)
{
}
#包括“glwidget.h”
#包括
GLwidget::GLwidget(QWidget*父项):QGLWidget(父项)
{
}
void GLwidget::initializeGL()
{
}
void GLwidget::paintGL()
{
**//我需要输入到这里**
}
void GLwidget::resizeGL(整数宽度、整数高度)
{
}
感谢您的帮助:)这可以通过使用一些常见的面向对象思想来解决,即带有setter函数的成员变量。在QGLWidget(glwidget.h)的子类中添加一些成员变量
private:
int m_my_int_value;
double m_my_double_value;
然后,您还需要一些用于这些值的setter函数(也在glwidget.h中)
您可以将这些函数的声明放在glwidget.cpp中
void GLwidget::Set_my_int_value(int val)
{
if(val != m_my_int_value)
{
m_my_int_value = val;
update();
}
}
void GLwidget::Set_my_double_value(double val)
{
if(val != m_my_double_value)
{
m_my_double_value = val;
update();
}
}
在on_click函数中调用这些setter函数。这些值将在您的paintGL实现中被访问。这可以通过使用一些常见的面向对象思想来解决,即带有setter函数的成员变量。在QGLWidget(glwidget.h)的子类中添加一些成员变量
private:
int m_my_int_value;
double m_my_double_value;
然后,您还需要一些用于这些值的setter函数(也在glwidget.h中)
您可以将这些函数的声明放在glwidget.cpp中
void GLwidget::Set_my_int_value(int val)
{
if(val != m_my_int_value)
{
m_my_int_value = val;
update();
}
}
void GLwidget::Set_my_double_value(double val)
{
if(val != m_my_double_value)
{
m_my_double_value = val;
update();
}
}
在on_click函数中调用这些setter函数。这些值将在您的paintGL实现中被访问。惯用的方法是使小部件成为值的显示,值是小部件的属性。这就是所有Qt控件的工作方式,例如
QLabel
可以显示一些文本,并且具有使用setText
设置的text
属性。一旦用新文本调用了setText
,标签就会知道如何自我更新。因此:
class DataView : public QOpenGLWidget
{
Q_OBJECT
Q_PROPERTY(double principal READ principal WRITE setPrincipal)
Q_PROPERTY(int amortizationPeriod READ amortizationPeriod WRITE setAmortizationPeriod)
...
double m_principal = {};
int m_amortizationPeriod = {};
public:
explicit GLwidget(QWidget *parent = {}) : QOpenGLWidget(parent) {}
void initializeGL() override;
void paintGL() override;
void resizeGL(int w, int h) override;
double principal() const { return m_principal; }
void setPrincipal(double principal) {
if (m_principal == principal) return;
m_principal = principal;
update();
}
int amortizationPeriod() const { return m_amortizationPeriod; }
void setAmortizationPeriod(int period) {
if (m_amortizationPeriod == period) return;
m_amortizationPeriod = period;
update();
}
...
};
update()
计划从事件循环重新绘制。更新请求被合并,因此在一行中设置多个属性只会对小部件绘制一次
因此,假设您将dataView
作为Ui表单的一个元素:
void MainWindow::on_pushButton_Calculate_clicked()
{
auto principal = inputcheck(ui->lineEdit_loan, loan);
auto amortizationPeriod = inputcheck(ui->lineEdit_maturity, maturity);
...
ui->dataView->setPrincipal(principal);
ui->dataView->setAmortizationPeriod(amortizationPeriod);
...
}
也许您希望动态地将dataView
显示为一个新的顶级窗口:
void MainWindow::on_pushButton_Calculate_clicked()
{
auto principal = inputcheck(ui->lineEdit_loan, loan);
auto amortizationPeriod = inputcheck(ui->lineEdit_maturity, maturity);
...
auto dataView = new DataView(this);
dataView->setWindowFlags(dataWidget->windowFlags() | Qt::Window);
dataView->setPrincipal(principal);
dataView->setAmortizationPeriod(amortizationPeriod);
...
dataView->show();
}
void MainWindow::on_pushButton_Calculate_clicked()
{
Loan loan;
loan.principal = inputcheck(ui->lineEdit_loan, loan);
loan.amortizationPeriod = inputcheck(ui->lineEdit_maturity, maturity);
...
auto dataView = new DataView(this);
dataView->setWindowFlags(dataView->windowFlags() | Qt::Window);
dataView->setLoan(loan);
dataView->show();
}
如果希望更方便地传递数据,可以将所有属性绑定到表示贷款的数据类型中:
struct Loan {
double principal = {};
int amortizationPeriod = {};
...
bool operator==(const Loan & o) const {
return
qFuzzyCompare(principal, o.principal)
&& amortizationPeriod == o.amortizationPeriod
&& ...;
// use qFuzzyCompare when comparing floating point values
}
};
Q_DECLARE_METATYPE(Loan)
class DataView : public QOpenGLWidget
{
Q_OBJECT
Q_PROPERTY(Loan loan READ loan WRITE setLoan)
Loan m_loan;
public:
explicit GLwidget(QWidget *parent = {}) : QOpenGLWidget(parent) {}
void initializeGL() override;
void paintGL() override;
void resizeGL(int w, int h) override;
const Loan & loan() const { return m_loan; }
Loan getLoan() const { return m_loan; }
void setLoan(const Loan & loan) {
if (m_loan == loan) return;
m_loan = loan;
update();
}
};
方便时,可以使用getLoan
获取贷款的可修改副本。通常的loan
getter成本较低,因为它返回对内部数据的常量引用,而不是副本
然后:
如果您希望将数据视图
动态显示为新的顶级窗口:
void MainWindow::on_pushButton_Calculate_clicked()
{
auto principal = inputcheck(ui->lineEdit_loan, loan);
auto amortizationPeriod = inputcheck(ui->lineEdit_maturity, maturity);
...
auto dataView = new DataView(this);
dataView->setWindowFlags(dataWidget->windowFlags() | Qt::Window);
dataView->setPrincipal(principal);
dataView->setAmortizationPeriod(amortizationPeriod);
...
dataView->show();
}
void MainWindow::on_pushButton_Calculate_clicked()
{
Loan loan;
loan.principal = inputcheck(ui->lineEdit_loan, loan);
loan.amortizationPeriod = inputcheck(ui->lineEdit_maturity, maturity);
...
auto dataView = new DataView(this);
dataView->setWindowFlags(dataView->windowFlags() | Qt::Window);
dataView->setLoan(loan);
dataView->show();
}
您还可以将数据视图与main窗口完全解耦,并通过信号将数据传递出去:
class MainWindow : public QMainWindow {
...
public:
Q_SLOT newLoan(const Loan &);
...
};
void MainWindow::on_pushButton_Calculate_clicked()
{
Loan loan;
loan.principal = inputcheck(ui->lineEdit_loan, loan);
loan.amortizationPeriod = inputcheck(ui->lineEdit_maturity, maturity);
...
emit newLoan(loan);
}
int main(int argc, char ** argv) {
QApplication app(argc, argv);
MainWindow mainWindow;
DataView dataView;
QObject::connect(&mainWindow, &MainWindow::newLoan, [&](const Loan & loan){
dataView.setLoan(loan);
dataView.show();
});
mainWindow.show();
return app.exec();
}
如果数据视图始终可见,您将有:
int main(int argc, char ** argv) {
QApplication app(argc, argv);
MainWindow mainWindow;
DataView dataView;
QObject::connect(&mainWindow, &MainWindow::newLoan, &dataView, &DataView::setLoan);
mainWindow.show();
dataView.show();
return app.exec();
}
惯用的方法是使小部件成为值的显示,值是小部件的属性。这就是所有Qt控件的工作方式,例如QLabel
可以显示一些文本,并且具有使用setText
设置的text
属性。一旦用新文本调用了setText
,标签就会知道如何自我更新。因此:
class DataView : public QOpenGLWidget
{
Q_OBJECT
Q_PROPERTY(double principal READ principal WRITE setPrincipal)
Q_PROPERTY(int amortizationPeriod READ amortizationPeriod WRITE setAmortizationPeriod)
...
double m_principal = {};
int m_amortizationPeriod = {};
public:
explicit GLwidget(QWidget *parent = {}) : QOpenGLWidget(parent) {}
void initializeGL() override;
void paintGL() override;
void resizeGL(int w, int h) override;
double principal() const { return m_principal; }
void setPrincipal(double principal) {
if (m_principal == principal) return;
m_principal = principal;
update();
}
int amortizationPeriod() const { return m_amortizationPeriod; }
void setAmortizationPeriod(int period) {
if (m_amortizationPeriod == period) return;
m_amortizationPeriod = period;
update();
}
...
};
update()
计划从事件循环重新绘制。更新请求被合并,thu