SCPI commands for manual control dialog

This commit is contained in:
Jan Käberich 2021-07-02 21:59:18 +02:00
parent 12b2a0d5ca
commit 0c3714d80c
7 changed files with 670 additions and 5 deletions

6
.gitignore vendored
View File

@ -5,4 +5,10 @@
*.op.raw *.op.raw
*.raw *.raw
*.vnafw *.vnafw
*.aux
*.log
*.synctex.gz
*.xcf
*.out
*.toc
Hardware/Renderings Hardware/Renderings

View File

@ -184,6 +184,399 @@ ManualControlDialog::~ManualControlDialog()
delete ui; delete ui;
} }
void ManualControlDialog::setHighSourceChipEnable(bool enable)
{
ui->SourceCE->setChecked(enable);
}
bool ManualControlDialog::getHighSourceChipEnable()
{
return ui->SourceCE->isChecked();
}
void ManualControlDialog::setHighSourceRFEnable(bool enable)
{
ui->SourceRFEN->setChecked(enable);
}
bool ManualControlDialog::getHighSourceRFEnable()
{
return ui->SourceRFEN->isChecked();
}
bool ManualControlDialog::getHighSourceLocked()
{
return ui->SourceLocked->isChecked();
}
bool ManualControlDialog::setHighSourcePower(int dBm)
{
switch(dBm) {
case -4:
ui->SourceHighPower->setCurrentIndex(0);
break;
case -1:
ui->SourceHighPower->setCurrentIndex(1);
break;
case 2:
ui->SourceHighPower->setCurrentIndex(2);
break;
case 5:
ui->SourceHighPower->setCurrentIndex(3);
break;
default:
// invalid power setting
return false;
}
return true;
}
int ManualControlDialog::getHighSourcePower()
{
int powers[4] = {-4,-1,2,5};
return powers[ui->SourceHighPower->currentIndex()];
}
void ManualControlDialog::setHighSourceFrequency(double f)
{
ui->SourceHighFrequency->setValue(f);
}
double ManualControlDialog::getHighSourceFrequency()
{
return ui->SourceHighFrequency->value();
}
void ManualControlDialog::setHighSourceLPF(ManualControlDialog::LPF lpf)
{
switch(lpf) {
case LPF::M947:
ui->SourceLowpass->setCurrentIndex(0);
break;
case LPF::M1880:
ui->SourceLowpass->setCurrentIndex(1);
break;
case LPF::M3500:
ui->SourceLowpass->setCurrentIndex(2);
break;
case LPF::None:
ui->SourceLowpass->setCurrentIndex(3);
break;
}
}
ManualControlDialog::LPF ManualControlDialog::getHighSourceLPF()
{
LPF lpfs[4] = {LPF::M947, LPF::M1880, LPF::M3500, LPF::None};
return lpfs[ui->SourceLowpass->currentIndex()];
}
void ManualControlDialog::setLowSourceEnable(bool enable)
{
ui->SourceLowEnable->setChecked(enable);
}
bool ManualControlDialog::getLowSourceEnable()
{
return ui->SourceLowEnable->isChecked();
}
bool ManualControlDialog::setLowSourcePower(int mA)
{
switch(mA) {
case 2:
ui->SourceLowPower->setCurrentIndex(0);
break;
case 4:
ui->SourceLowPower->setCurrentIndex(1);
break;
case 6:
ui->SourceLowPower->setCurrentIndex(2);
break;
case 8:
ui->SourceLowPower->setCurrentIndex(3);
break;
default:
// invalid power setting
return false;
}
return true;
}
int ManualControlDialog::getLowSourcePower()
{
int powers[4] = {2,4,6,8};
return powers[ui->SourceLowPower->currentIndex()];
}
void ManualControlDialog::setLowSourceFrequency(double f)
{
ui->SourceLowFrequency->setValue(f);
}
double ManualControlDialog::getLowSourceFrequency()
{
return ui->SourceLowFrequency->value();
}
void ManualControlDialog::setHighband(bool high)
{
if(high) {
ui->SwitchHighband->setChecked(true);
} else {
ui->SwitchLowband->setChecked(true);
}
}
bool ManualControlDialog::getHighband()
{
return ui->SwitchHighband->isChecked();
}
void ManualControlDialog::setAttenuator(double att)
{
ui->Attenuator->setValue(att);
}
double ManualControlDialog::getAttenuator()
{
return ui->Attenuator->value();
}
void ManualControlDialog::setAmplifierEnable(bool enable)
{
ui->AmplifierEnable->setChecked(enable);
}
bool ManualControlDialog::getAmplifierEnable()
{
return ui->AmplifierEnable->isChecked();
}
bool ManualControlDialog::setPortSwitch(int port)
{
switch(port) {
case 1:
ui->Port1Switch->setChecked(true);
break;
case 2:
ui->Port2Switch->setChecked(true);
break;
default:
// invalid port
return false;
}
return true;
}
int ManualControlDialog::getPortSwitch()
{
if(ui->Port1Switch->isChecked()) {
return 1;
} else {
return 2;
}
}
void ManualControlDialog::setLO1ChipEnable(bool enable)
{
ui->LO1CE->setChecked(enable);
}
bool ManualControlDialog::getLO1ChipEnable()
{
return ui->LO1CE->isChecked();
}
void ManualControlDialog::setLO1RFEnable(bool enable)
{
ui->LO1RFEN->setChecked(enable);
}
bool ManualControlDialog::getLO1RFEnable()
{
return ui->LO1RFEN->isChecked();
}
bool ManualControlDialog::getLO1Locked()
{
return ui->LO1locked->isChecked();
}
void ManualControlDialog::setLO1Frequency(double f)
{
ui->LO1FreqType->setCurrentIndex(1);
ui->LO1Frequency->setValue(f);
}
double ManualControlDialog::getLO1Frequency()
{
return ui->LO1Frequency->value();
}
void ManualControlDialog::setIF1Frequency(double f)
{
ui->LO1FreqType->setCurrentIndex(0);
ui->IF1->setValue(f);
}
double ManualControlDialog::getIF1Frequency()
{
return ui->IF1->value();
}
void ManualControlDialog::setLO2Enable(bool enable)
{
ui->LO2EN->setChecked(enable);
}
bool ManualControlDialog::getLO2Enable()
{
return ui->LO2EN->isChecked();
}
void ManualControlDialog::setLO2Frequency(double f)
{
ui->LO2FreqType->setCurrentIndex(1);
ui->LO2Frequency->setValue(f);
}
double ManualControlDialog::getLO2Frequency()
{
return ui->LO2Frequency->value();
}
void ManualControlDialog::setIF2Frequency(double f)
{
ui->LO2FreqType->setCurrentIndex(0);
ui->IF2->setValue(f);
}
double ManualControlDialog::getIF2Frequency()
{
return ui->IF2->value();
}
void ManualControlDialog::setPort1Enable(bool enable)
{
ui->Port1Enable->setChecked(enable);
}
bool ManualControlDialog::getPort1Enable()
{
return ui->Port1Enable->isChecked();
}
void ManualControlDialog::setPort2Enable(bool enable)
{
ui->Port2Enable->setChecked(enable);
}
bool ManualControlDialog::getPort2Enable()
{
return ui->Port2Enable->isChecked();
}
void ManualControlDialog::setRefEnable(bool enable)
{
ui->RefEnable->setChecked(enable);
}
bool ManualControlDialog::getRefEnable()
{
return ui->RefEnable->isChecked();
}
void ManualControlDialog::setNumSamples(int samples)
{
ui->Samples->setValue(samples);
}
int ManualControlDialog::getNumSamples()
{
return ui->Samples->value();
}
void ManualControlDialog::setWindow(ManualControlDialog::Window w)
{
ui->cbWindow->setCurrentIndex((int) w);
}
ManualControlDialog::Window ManualControlDialog::getWindow()
{
return (Window) ui->cbWindow->currentIndex();
}
int ManualControlDialog::getPort1MinADC()
{
return ui->port1min->text().toInt();
}
int ManualControlDialog::getPort1MaxADC()
{
return ui->port1max->text().toInt();
}
double ManualControlDialog::getPort1Magnitude()
{
return ui->port1mag->text().toDouble();
}
double ManualControlDialog::getPort1Phase()
{
return ui->port1phase->text().toDouble();
}
std::complex<double> ManualControlDialog::getPort1Referenced()
{
return port1referenced;
}
int ManualControlDialog::getPort2MinADC()
{
return ui->port2min->text().toInt();
}
int ManualControlDialog::getPort2MaxADC()
{
return ui->port2max->text().toInt();
}
double ManualControlDialog::getPort2Magnitude()
{
return ui->port2mag->text().toDouble();
}
double ManualControlDialog::getPort2Phase()
{
return ui->port2phase->text().toDouble();
}
std::complex<double> ManualControlDialog::getPort2Referenced()
{
return port2referenced;
}
int ManualControlDialog::getRefMinADC()
{
return ui->refmin->text().toInt();
}
int ManualControlDialog::getRefMaxADC()
{
return ui->refmax->text().toInt();
}
double ManualControlDialog::getRefMagnitude()
{
return ui->refmag->text().toDouble();
}
double ManualControlDialog::getRefPhase()
{
return ui->refphase->text().toDouble();
}
void ManualControlDialog::NewStatus(Protocol::ManualStatus status) void ManualControlDialog::NewStatus(Protocol::ManualStatus status)
{ {
// ADC values // ADC values
@ -205,8 +598,8 @@ void ManualControlDialog::NewStatus(Protocol::ManualStatus status)
ui->refmag->setText(QString::number(abs(ref))); ui->refmag->setText(QString::number(abs(ref)));
ui->refphase->setText(QString::number(arg(ref)*180/M_PI)); ui->refphase->setText(QString::number(arg(ref)*180/M_PI));
auto port1referenced = port1 / ref; port1referenced = port1 / ref;
auto port2referenced = port2 / ref; port2referenced = port2 / ref;
auto port1db = Util::SparamTodB(port1referenced); auto port1db = Util::SparamTodB(port1referenced);
auto port2db = Util::SparamTodB(port2referenced); auto port2db = Util::SparamTodB(port2referenced);

View File

@ -3,6 +3,7 @@
#include <QDialog> #include <QDialog>
#include "device.h" #include "device.h"
#include <complex>
namespace Ui { namespace Ui {
class ManualControlDialog; class ManualControlDialog;
@ -16,6 +17,90 @@ public:
explicit ManualControlDialog(Device &dev, QWidget *parent = nullptr); explicit ManualControlDialog(Device &dev, QWidget *parent = nullptr);
~ManualControlDialog(); ~ManualControlDialog();
void setHighSourceChipEnable(bool enable);
bool getHighSourceChipEnable();
void setHighSourceRFEnable(bool enable);
bool getHighSourceRFEnable();
bool getHighSourceLocked();
bool setHighSourcePower(int dBm);
int getHighSourcePower();
void setHighSourceFrequency(double f);
double getHighSourceFrequency();
enum class LPF {
M947,
M1880,
M3500,
None,
};
void setHighSourceLPF(LPF lpf);
LPF getHighSourceLPF();
void setLowSourceEnable(bool enable);
bool getLowSourceEnable();
bool setLowSourcePower(int mA);
int getLowSourcePower();
void setLowSourceFrequency(double f);
double getLowSourceFrequency();
void setHighband(bool high);
bool getHighband();
void setAttenuator(double att);
double getAttenuator();
void setAmplifierEnable(bool enable);
bool getAmplifierEnable();
bool setPortSwitch(int port);
int getPortSwitch();
void setLO1ChipEnable(bool enable);
bool getLO1ChipEnable();
void setLO1RFEnable(bool enable);
bool getLO1RFEnable();
bool getLO1Locked();
void setLO1Frequency(double f);
double getLO1Frequency();
void setIF1Frequency(double f);
double getIF1Frequency();
void setLO2Enable(bool enable);
bool getLO2Enable();
void setLO2Frequency(double f);
double getLO2Frequency();
void setIF2Frequency(double f);
double getIF2Frequency();
void setPort1Enable(bool enable);
bool getPort1Enable();
void setPort2Enable(bool enable);
bool getPort2Enable();
void setRefEnable(bool enable);
bool getRefEnable();
void setNumSamples(int samples);
int getNumSamples();
enum class Window {
None = 0,
Kaiser = 1,
Hann = 2,
FlatTop = 3
};
void setWindow(Window w);
Window getWindow();
int getPort1MinADC();
int getPort1MaxADC();
double getPort1Magnitude();
double getPort1Phase();
std::complex<double> getPort1Referenced();
int getPort2MinADC();
int getPort2MaxADC();
double getPort2Magnitude();
double getPort2Phase();
std::complex<double> getPort2Referenced();
int getRefMinADC();
int getRefMaxADC();
double getRefMagnitude();
double getRefPhase();
public slots: public slots:
void NewStatus(Protocol::ManualStatus status); void NewStatus(Protocol::ManualStatus status);
@ -23,6 +108,8 @@ private:
void UpdateDevice(); void UpdateDevice();
Ui::ManualControlDialog *ui; Ui::ManualControlDialog *ui;
Device &dev; Device &dev;
std::complex<double> port1referenced;
std::complex<double> port2referenced;
}; };
#endif // MANUALCONTROLDIALOG_H #endif // MANUALCONTROLDIALOG_H

View File

@ -64,6 +64,7 @@ static const QString APP_GIT_HASH = QString(GITHASH);
AppWindow::AppWindow(QWidget *parent) AppWindow::AppWindow(QWidget *parent)
: QMainWindow(parent) : QMainWindow(parent)
, deviceActionGroup(new QActionGroup(this)) , deviceActionGroup(new QActionGroup(this))
, manual(nullptr)
, ui(new Ui::MainWindow) , ui(new Ui::MainWindow)
, server(nullptr) , server(nullptr)
, appVersion(APP_VERSION) , appVersion(APP_VERSION)
@ -544,6 +545,159 @@ void AppWindow::SetupSCPI()
scpi.add(vna); scpi.add(vna);
scpi.add(generator); scpi.add(generator);
scpi.add(spectrumAnalyzer); scpi.add(spectrumAnalyzer);
auto scpi_manual = new SCPINode("MANual");
scpi_manual->add(new SCPICommand("STArt",[=](QStringList) -> QString {
StartManualControl();
return "";
}, nullptr));
scpi_manual->add(new SCPICommand("STOp",[=](QStringList) -> QString {
manual->close();
delete manual;
return "";
}, nullptr));
auto addBooleanManualSetting = [=](QString cmd, void(ManualControlDialog::*set)(bool), bool(ManualControlDialog::*get)(void)) {
scpi_manual->add(new SCPICommand(cmd, [=](QStringList params) -> QString {
bool enable;
if(!manual || !SCPI::paramToBool(params, 0, enable)) {
return "ERROR";
}
auto set_fn = std::bind(set, manual, std::placeholders::_1);
set_fn(enable);
return "";
}, [=](QStringList) -> QString {
if(!manual) {
return "ERROR";
}
auto get_fn = std::bind(get, manual);
return get_fn() ? "TRUE" : "FALSE";
}));
};
auto addDoubleManualSetting = [=](QString cmd, void(ManualControlDialog::*set)(double), double(ManualControlDialog::*get)(void)) {
scpi_manual->add(new SCPICommand(cmd, [=](QStringList params) -> QString {
double value;
if(!manual || !SCPI::paramToDouble(params, 0, value)) {
return "ERROR";
}
auto set_fn = std::bind(set, manual, std::placeholders::_1);
set_fn(value);
return "";
}, [=](QStringList) -> QString {
if(!manual) {
return "ERROR";
}
auto get_fn = std::bind(get, manual);
return QString::number(get_fn());
}));
};
auto addIntegerManualSetting = [=](QString cmd, void(ManualControlDialog::*set)(int), int(ManualControlDialog::*get)(void)) {
scpi_manual->add(new SCPICommand(cmd, [=](QStringList params) -> QString {
double value;
if(!manual || !SCPI::paramToDouble(params, 0, value)) {
return "ERROR";
}
auto set_fn = std::bind(set, manual, std::placeholders::_1);
set_fn(value);
return "";
}, [=](QStringList) -> QString {
if(!manual) {
return "ERROR";
}
auto get_fn = std::bind(get, manual);
return QString::number(get_fn());
}));
};
auto addIntegerManualSettingWithReturnValue = [=](QString cmd, bool(ManualControlDialog::*set)(int), int(ManualControlDialog::*get)(void)) {
scpi_manual->add(new SCPICommand(cmd, [=](QStringList params) -> QString {
double value;
if(!manual || !SCPI::paramToDouble(params, 0, value)) {
return "ERROR";
}
auto set_fn = std::bind(set, manual, std::placeholders::_1);
if(set_fn(value)) {
return "";
} else {
return "ERROR";
}
}, [=](QStringList) -> QString {
if(!manual) {
return "ERROR";
}
auto get_fn = std::bind(get, manual);
return QString::number(get_fn());
}));
};
auto addIntegerManualQuery = [=](QString cmd, int(ManualControlDialog::*get)(void)) {
scpi_manual->add(new SCPICommand(cmd, nullptr, [=](QStringList) -> QString {
if(!manual) {
return "ERROR";
}
auto get_fn = std::bind(get, manual);
return QString::number(get_fn());
}));
};
auto addDoubleManualQuery = [=](QString cmd, double(ManualControlDialog::*get)(void)) {
scpi_manual->add(new SCPICommand(cmd, nullptr, [=](QStringList) -> QString {
if(!manual) {
return "ERROR";
}
auto get_fn = std::bind(get, manual);
return QString::number(get_fn());
}));
};
auto addComplexManualQuery = [=](QString cmd, std::complex<double>(ManualControlDialog::*get)(void)) {
scpi_manual->add(new SCPICommand(cmd, nullptr, [=](QStringList) -> QString {
if(!manual) {
return "ERROR";
}
auto get_fn = std::bind(get, manual);
auto res = get_fn();
return QString::number(res.real())+","+QString::number(res.imag());
}));
};
addBooleanManualSetting("HSRC_CE", &ManualControlDialog::setHighSourceChipEnable, &ManualControlDialog::getHighSourceChipEnable);
addBooleanManualSetting("HSRC_RFEN", &ManualControlDialog::setHighSourceRFEnable, &ManualControlDialog::getHighSourceRFEnable);
addIntegerManualSettingWithReturnValue("HSRC_PWR", &ManualControlDialog::setHighSourcePower, &ManualControlDialog::getHighSourcePower);
addDoubleManualSetting("HSRC_FREQ", &ManualControlDialog::setHighSourceFrequency, &ManualControlDialog::getHighSourceFrequency);
addBooleanManualSetting("LSRC_EN", &ManualControlDialog::setLowSourceEnable, &ManualControlDialog::getLowSourceEnable);
addIntegerManualSettingWithReturnValue("LSRC_PWR", &ManualControlDialog::setLowSourcePower, &ManualControlDialog::getLowSourcePower);
addDoubleManualSetting("LSRC_FREQ", &ManualControlDialog::setLowSourceFrequency, &ManualControlDialog::getLowSourceFrequency);
addBooleanManualSetting("BAND_SW", &ManualControlDialog::setHighband, &ManualControlDialog::getHighband);
addDoubleManualSetting("ATTenuator", &ManualControlDialog::setAttenuator, &ManualControlDialog::getAttenuator);
addBooleanManualSetting("AMP_EN", &ManualControlDialog::setAmplifierEnable, &ManualControlDialog::getAmplifierEnable);
addIntegerManualSettingWithReturnValue("PORT_SW", &ManualControlDialog::setPortSwitch, &ManualControlDialog::getPortSwitch);
addBooleanManualSetting("LO1_CE", &ManualControlDialog::setLO1ChipEnable, &ManualControlDialog::getLO1ChipEnable);
addBooleanManualSetting("LO1_RFEN", &ManualControlDialog::setLO1RFEnable, &ManualControlDialog::getLO1RFEnable);
addDoubleManualSetting("LO1_FREQ", &ManualControlDialog::setLO1Frequency, &ManualControlDialog::getLO1Frequency);
addDoubleManualSetting("IF1_FREQ", &ManualControlDialog::setIF1Frequency, &ManualControlDialog::getIF1Frequency);
addBooleanManualSetting("LO2_EN", &ManualControlDialog::setLO2Enable, &ManualControlDialog::getLO2Enable);
addDoubleManualSetting("LO2_FREQ", &ManualControlDialog::setLO2Frequency, &ManualControlDialog::getLO2Frequency);
addDoubleManualSetting("IF2_FREQ", &ManualControlDialog::setIF2Frequency, &ManualControlDialog::getIF2Frequency);
addBooleanManualSetting("PORT1_EN", &ManualControlDialog::setPort1Enable, &ManualControlDialog::getPort1Enable);
addBooleanManualSetting("PORT2_EN", &ManualControlDialog::setPort2Enable, &ManualControlDialog::getPort2Enable);
addBooleanManualSetting("REF_EN", &ManualControlDialog::setRefEnable, &ManualControlDialog::getRefEnable);
addIntegerManualSetting("LSRC_FREQ", &ManualControlDialog::setNumSamples, &ManualControlDialog::getNumSamples);
addIntegerManualQuery("PORT1_MIN", &ManualControlDialog::getPort1MinADC);
addIntegerManualQuery("PORT1_MAX", &ManualControlDialog::getPort1MaxADC);
addDoubleManualQuery("PORT1_MAG", &ManualControlDialog::getPort1Magnitude);
addDoubleManualQuery("PORT1_PHAse", &ManualControlDialog::getPort1Phase);
addComplexManualQuery("PORT1_REFerenced", &ManualControlDialog::getPort1Referenced);
addIntegerManualQuery("PORT2_MIN", &ManualControlDialog::getPort2MinADC);
addIntegerManualQuery("PORT2_MAX", &ManualControlDialog::getPort2MaxADC);
addDoubleManualQuery("PORT2_MAG", &ManualControlDialog::getPort2Magnitude);
addDoubleManualQuery("PORT2_PHAse", &ManualControlDialog::getPort2Phase);
addComplexManualQuery("PORT2_REFerenced", &ManualControlDialog::getPort2Referenced);
addIntegerManualQuery("REF_MIN", &ManualControlDialog::getRefMinADC);
addIntegerManualQuery("REF_MAX", &ManualControlDialog::getRefMaxADC);
addDoubleManualQuery("REF_MAG", &ManualControlDialog::getRefMagnitude);
addDoubleManualQuery("REF_PHAse", &ManualControlDialog::getRefPhase);
scpi.add(scpi_manual);
} }
void AppWindow::StartTCPServer(int port) void AppWindow::StartTCPServer(int port)
@ -596,13 +750,18 @@ int AppWindow::UpdateDeviceList()
void AppWindow::StartManualControl() void AppWindow::StartManualControl()
{ {
auto control = new ManualControlDialog(*device, this); if(manual) {
connect(control, &QDialog::finished, [=](){ // dialog already active, nothing to do
return;
}
manual = new ManualControlDialog(*device, this);
connect(manual, &QDialog::finished, [=](){
manual = nullptr;
if(device) { if(device) {
Mode::getActiveMode()->initializeDevice(); Mode::getActiveMode()->initializeDevice();
} }
}); });
control->show(); manual->show();
} }
void AppWindow::UpdateReference() void AppWindow::UpdateReference()

View File

@ -21,6 +21,7 @@
#include <QCommandLineParser> #include <QCommandLineParser>
#include "scpi.h" #include "scpi.h"
#include "tcpserver.h" #include "tcpserver.h"
#include "Device/manualcontroldialog.h"
namespace Ui { namespace Ui {
class MainWindow; class MainWindow;
@ -80,6 +81,8 @@ private:
QString deviceSerial; QString deviceSerial;
QActionGroup *deviceActionGroup; QActionGroup *deviceActionGroup;
ManualControlDialog *manual;
// Modes // Modes
VNA *vna; VNA *vna;
Generator *generator; Generator *generator;

View File

@ -62,6 +62,22 @@ bool SCPI::paramToLong(QStringList params, int index, long &dest)
return okay; return okay;
} }
bool SCPI::paramToBool(QStringList params, int index, bool &dest)
{
if(index >= params.size()) {
return false;
}
bool okay = false;
if(params[index] == "TRUE") {
dest = true;
okay = true;
} else if(params[index] == "FALSE") {
dest = false;
okay = true;
}
return okay;
}
void SCPI::input(QString line) void SCPI::input(QString line)
{ {
auto cmds = line.split(";"); auto cmds = line.split(";");

View File

@ -54,6 +54,7 @@ public:
static bool paramToDouble(QStringList params, int index, double &dest); static bool paramToDouble(QStringList params, int index, double &dest);
static bool paramToULong(QStringList params, int index, unsigned long &dest); static bool paramToULong(QStringList params, int index, unsigned long &dest);
static bool paramToLong(QStringList params, int index, long &dest); static bool paramToLong(QStringList params, int index, long &dest);
static bool paramToBool(QStringList params, int index, bool &dest);
public slots: public slots:
void input(QString line); void input(QString line);