MainWindow() { QToolBar *toolBar = new QToolBar(this); toolBar->setFixedHeight(80); #if QT_VERSION < 0x040000 setDockEnabled(TornOff, true); setRightJustification(true); #else toolBar->setAllowedAreas(Qt::TopToolBarArea | Qt::BottomToolBarArea); #endif QWidget *hBox = new QWidget(toolBar); QLabel *label = new QLabel("Timer Interval", hBox); QwtCounter *counter = new QwtCounter(hBox); counter->setRange(-1.0, 100.0, 1.0); QHBoxLayout *layout = new QHBoxLayout(hBox); layout->addWidget(label); layout->addWidget(counter); layout->addWidget(new QWidget(hBox), 10); // spacer); #if QT_VERSION >= 0x040000 toolBar->addWidget(hBox); #endif addToolBar(toolBar); DataPlot *plot = new DataPlot(this); setCentralWidget(plot); connect(counter, SIGNAL(valueChanged(double)), plot, SLOT(setTimerInterval(double)) ); counter->setValue(20.0); }
MainWindow(ResourceFinder *rf) { //if (VERBOSE) fprintf(stderr, "Passing RF by address ..."); resFind = rf; //if (VERBOSE) fprintf(stderr, "done \n"); Property options; options.fromString(resFind->toString()); Value &robot = options.find("robot"); Value &part = options.find("part"); Value &rows = options.find("rows"); Value &cols = options.find("cols"); if (!options.check("robot")) printf("Missing --robot option. Using icub.\n"); if (!options.check("part")) printf("Missing --part option. Using head.\n"); if (!options.check("local")) printf("Missing --name option. Using /portScope/vector:i.\n"); if (!options.check("remote")) printf("Missing --remote option. Will wait for the connection...\n"); if (!options.check("rows")) printf("Missing --rows option. Disabling subplotting.\n"); //if (VERBOSE) fprintf(stderr, "Start plotting the GUI\n"); QToolBar *toolBar = new QToolBar(this); toolBar->setFixedHeight(80); #if QT_VERSION < 0x040000 setDockEnabled(TornOff, true); setRightJustification(true); #else toolBar->setAllowedAreas(Qt::TopToolBarArea | Qt::BottomToolBarArea); #endif QWidget *hBox = new QWidget(toolBar); QLabel *label = new QLabel("Timer Interval", hBox); QwtCounter *counter = new QwtCounter(hBox); QLabel *labelActions = new QLabel("Actions", hBox); QPushButton *toggleAcquireButton = new QPushButton("stop", hBox, "stop"); counter->setRange(-1.0, 1000.0, 1.0); QHBoxLayout *layout = new QHBoxLayout(hBox); layout->addWidget(label); layout->addWidget(counter); layout->addWidget(labelActions); layout->addWidget(toggleAcquireButton); layout->addWidget(new QWidget(hBox), 10); // spacer); #if QT_VERSION >= 0x040000 toolBar->addWidget(hBox); #endif addToolBar(toolBar); if (options.check("rows")) nRows = rows.asInt(); else nRows = 1; if (options.check("cols")) nCols = cols.asInt(); else nCols = nRows; nPlots = nRows*nCols; nPortInputsInPlots = new int[nPlots]; QGrid *grid = new QGrid( nRows, Qt::Vertical, this ); plot = new DataPlot*[nPlots]; setCentralWidget(grid); for( int r = 0 ; r < nRows ; r++ ) { for( int c = 0 ; c < nCols ; c++ ) { char rcS[256]; sprintf(rcS, "%d%d", r, c); ConstString rS(rcS); ConstString local; local = resFind->find("local").toString(); //local port name local = local + rcS; //dataPlot creation plot[r+nRows*c] = new DataPlot(grid); //dataPlot set plot to read from setInputPort(resFind, r+nRows*c, local); //dataPlot set indeces of ports to plot setIndexMask(resFind, r+nRows*c, nPortInputsInPlots[r+nRows*c]); } } for( int r = 0 ; r < nRows ; r++ ) { for( int c = 0 ; c < nCols ; c++ ) { //stop acquisition button connect( toggleAcquireButton, SIGNAL(clicked()), plot[r+nRows*c], SLOT(toggleAcquire()) ); plot[r+nRows*c]->initSignalDimensions(); //counter button connect(counter, SIGNAL(valueChanged(double)), plot[r+nRows*c], SLOT(setTimerInterval(double)) ); counter->setValue(50.0); QSizePolicy sizePolicy2(QSizePolicy::Maximum, QSizePolicy::Maximum); grid->setSizePolicy(sizePolicy2); QSizePolicy sizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); sizePolicy.setHeightForWidth(plot[r+nRows*c]->sizePolicy().hasHeightForWidth()); plot[r+nRows*c]->setSizePolicy(sizePolicy); //QSize gridSize= grid->sizeHint(); //gridSize.setWidth(500); //gridSize.setHeight(500); plot[r+nRows*c]->setMinimumWidth(10); plot[r+nRows*c]->setMaximumWidth(800); plot[r+nRows*c]->setMinimumHeight(10); plot[r+nRows*c]->setMaximumHeight(800); //if (VERBOSE) fprintf(stderr, "Grid max is: hInt=%d, vInt=%d\n", grid->maximumHeight(), grid->maximumWidth()); //if (VERBOSE) fprintf(stderr, "Plot max is: hInt=%d, vInt=%d\n", plot[r+nRows*c]->maximumHeight(), plot[r+nRows*c]->maximumWidth()); //QSize plotSize= plot[r+nRows*c]->sizeHint(); //if (VERBOSE) fprintf(stderr, "Plot Hint is: hInt=%d, vInt=%d\n", plotSize.height(), plotSize.width()); } } }
MainWindow::MainWindow( QWidget *parent ) : QWidget(parent), adChannel(0), psthLength(1000), psthBinw(20), spikeThres(1), psthOn(0), spikeDetected(false), time(0), linearAverage(0) { // initialize comedi const char *filename = "/dev/comedi0"; /* open the device */ if( (dev = comedi_open(filename)) == 0 ) { comedi_perror(filename); exit(1); } // do not produce NAN for out of range behaviour comedi_set_global_oor_behavior(COMEDI_OOR_NUMBER); maxdata = comedi_get_maxdata(dev, COMEDI_SUB_DEVICE, 0); crange = comedi_get_range(dev,COMEDI_SUB_DEVICE,0,0); numChannels = comedi_get_n_channels(dev, COMEDI_SUB_DEVICE); chanlist = new unsigned[numChannels]; /* Set up channel list */ for( int i=0; i<numChannels; i++ ) chanlist[i] = CR_PACK(i, COMEDI_RANGE_ID, AREF_GROUND); int ret = comedi_get_cmd_generic_timed( dev, COMEDI_SUB_DEVICE, &comediCommand, numChannels, (int)(1e9/(SAMPLING_RATE)) ); if(ret < 0) { printf("comedi_get_cmd_generic_timed failed\n"); exit(-1); } /* Modify parts of the command */ comediCommand.chanlist = chanlist; comediCommand.stop_src = TRIG_NONE; comediCommand.stop_arg = 0; /* comedi_command_test() tests a command to see if the * trigger sources and arguments are valid for the subdevice. * If a trigger source is invalid, it will be logically ANDed * with valid values (trigger sources are actually bitmasks), * which may or may not result in a valid trigger source. * If an argument is invalid, it will be adjusted to the * nearest valid value. In this way, for many commands, you * can test it multiple times until it passes. Typically, * if you can't get a valid command in two tests, the original * command wasn't specified very well. */ ret = comedi_command_test(dev, &comediCommand); if(ret < 0) { comedi_perror("comedi_command_test"); exit(-1); } fprintf(stderr, "first test returned %d\n", ret); ret = comedi_command_test(dev, &comediCommand); if(ret < 0) { comedi_perror("comedi_command_test"); exit(-1); } fprintf(stderr, "second test returned %d\n", ret); if(ret != 0) { fprintf(stderr,"Error preparing command\n"); exit(-1); } // the timing is done channel by channel // this means that the actual sampling rate is divided by // number of channels if ((comediCommand.convert_src == TRIG_TIMER)&&(comediCommand.convert_arg)) { sampling_rate=(((double)1E9 / comediCommand.convert_arg)/numChannels); } // the timing is done scan by scan (all channels at once) // the sampling rate is equivalent of the scan_begin_arg if ((comediCommand.scan_begin_src == TRIG_TIMER)&&(comediCommand.scan_begin_arg)) { sampling_rate=(double)1E9 / comediCommand.scan_begin_arg; } // 50Hz or 60Hz mains notch filter iirnotch = new Iir::Butterworth::BandStop<IIRORDER>; assert( iirnotch != NULL ); iirnotch->setup (IIRORDER, sampling_rate, NOTCH_F, NOTCH_F/10.0); /* start the command */ ret = comedi_command(dev, &comediCommand); if(ret < 0) { comedi_perror("comedi_command"); exit(1); } int subdev_flags = comedi_get_subdevice_flags(dev, COMEDI_SUB_DEVICE); if( (sigmaBoard = subdev_flags & SDF_LSAMPL) ) readSize = sizeof(lsampl_t) * numChannels; else readSize = sizeof(sampl_t) * numChannels; // Initialize data for plots for(int i=0; i<MAX_PSTH_LENGTH; i++) { xData[i] = i; // time axis yData[i] = 0; timeData[i] = double(i)*psthBinw; // psth time axis spikeCountData[i] = 0; psthData[i] = 0; } // the gui, straight forward QT/Qwt resize(640,420); QHBoxLayout *mainLayout = new QHBoxLayout( this ); QVBoxLayout *controlLayout = new QVBoxLayout; mainLayout->addLayout(controlLayout); QVBoxLayout *plotLayout = new QVBoxLayout; plotLayout->addStrut(400); mainLayout->addLayout(plotLayout); // two plots RawDataPlot = new DataPlot(xData, yData, psthLength, crange->max, crange->min, this); plotLayout->addWidget(RawDataPlot); RawDataPlot->show(); plotLayout->addSpacing(20); MyPsthPlot = new PsthPlot(timeData, psthData, psthLength/psthBinw, this); plotLayout->addWidget(MyPsthPlot); MyPsthPlot->show(); /*---- Buttons ----*/ // AD group QGroupBox *ADcounterGroup = new QGroupBox( "A/D Channel", this ); QVBoxLayout *ADcounterLayout = new QVBoxLayout; ADcounterGroup->setLayout(ADcounterLayout); ADcounterGroup->setAlignment(Qt::AlignJustify); ADcounterGroup->setSizePolicy( QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed) ); controlLayout->addWidget( ADcounterGroup ); QwtCounter *cntChannel = new QwtCounter(ADcounterGroup); cntChannel->setRange(0, numChannels-1, 1); cntChannel->setValue(adChannel); ADcounterLayout->addWidget(cntChannel); connect(cntChannel, SIGNAL(valueChanged(double)), SLOT(slotSetChannel(double))); filter50HzCheckBox = new QCheckBox( "50Hz filter" ); filter50HzCheckBox->setEnabled( true ); ADcounterLayout->addWidget(filter50HzCheckBox); // psth functions QGroupBox *PSTHfunGroup = new QGroupBox( "Actions", this ); QVBoxLayout *PSTHfunLayout = new QVBoxLayout; PSTHfunGroup->setLayout(PSTHfunLayout); PSTHfunGroup->setAlignment(Qt::AlignJustify); PSTHfunGroup->setSizePolicy( QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed) ); controlLayout->addWidget( PSTHfunGroup ); averagePsth = new QComboBox(PSTHfunGroup); averagePsth->addItem(tr("PSTH")); averagePsth->addItem(tr("VEP")); PSTHfunLayout->addWidget(averagePsth); connect( averagePsth, SIGNAL(currentIndexChanged(int)), SLOT(slotAveragePsth(int)) ); triggerPsth = new QPushButton(PSTHfunGroup); triggerPsth->setText("PSTH on"); triggerPsth->setCheckable(true); PSTHfunLayout->addWidget(triggerPsth); connect(triggerPsth, SIGNAL(clicked()), SLOT(slotTriggerPsth())); QPushButton *clearPsth = new QPushButton(PSTHfunGroup); clearPsth->setText("clear data"); PSTHfunLayout->addWidget(clearPsth); connect(clearPsth, SIGNAL(clicked()), SLOT(slotClearPsth())); QPushButton *savePsth = new QPushButton(PSTHfunGroup); savePsth->setText("save data"); PSTHfunLayout->addWidget(savePsth); connect(savePsth, SIGNAL(clicked()), SLOT(slotSavePsth())); // psth params QGroupBox *PSTHcounterGroup = new QGroupBox( "Parameters", this ); QVBoxLayout *PSTHcounterLayout = new QVBoxLayout; PSTHcounterGroup->setLayout(PSTHcounterLayout); PSTHcounterGroup->setAlignment(Qt::AlignJustify); PSTHcounterGroup->setSizePolicy( QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed) ); controlLayout->addWidget( PSTHcounterGroup ); QLabel *psthLengthLabel = new QLabel("Sweep length", PSTHcounterGroup); PSTHcounterLayout->addWidget(psthLengthLabel); QwtCounter *cntSLength = new QwtCounter(PSTHcounterGroup); cntSLength->setNumButtons(2); cntSLength->setIncSteps(QwtCounter::Button1, 10); cntSLength->setIncSteps(QwtCounter::Button2, 100); cntSLength->setRange(1, MAX_PSTH_LENGTH, 1); cntSLength->setValue(psthLength); PSTHcounterLayout->addWidget(cntSLength); connect(cntSLength, SIGNAL(valueChanged(double)), SLOT(slotSetPsthLength(double))); QLabel *binwidthLabel = new QLabel("Binwidth", PSTHcounterGroup); PSTHcounterLayout->addWidget(binwidthLabel); cntBinw = new QwtCounter(PSTHcounterGroup); cntBinw->setNumButtons(2); cntBinw->setIncSteps(QwtCounter::Button1, 1); cntBinw->setIncSteps(QwtCounter::Button2, 10); cntBinw->setRange(1, 100, 1); cntBinw->setValue(psthBinw); PSTHcounterLayout->addWidget(cntBinw); connect(cntBinw, SIGNAL(valueChanged(double)), SLOT(slotSetPsthBinw(double))); QLabel *thresholdLabel = new QLabel("Spike Threshold", PSTHcounterGroup); PSTHcounterLayout->addWidget(thresholdLabel); editSpikeT = new QTextEdit("0"); QFont editFont("Courier",14); QFontMetrics editMetrics(editFont); editSpikeT->setMaximumHeight ( editMetrics.height()*1.2 ); editSpikeT->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); editSpikeT->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); editSpikeT->setFont(editFont); PSTHcounterLayout->addWidget(editSpikeT); connect(editSpikeT, SIGNAL(textChanged()), SLOT(slotSetSpikeThres())); thresholdMarker = new QwtPlotMarker(); thresholdMarker->setValue(0,0); thresholdMarker->attach(RawDataPlot); thresholdMarker->setLineStyle(QwtPlotMarker::HLine); // Generate timer event every 50ms (void)startTimer(50); }
MainWindow::MainWindow( QWidget *parent ): QMainWindow( parent ) { d_plot = new Plot( this ); const int margin = 5; d_plot->setContentsMargins( margin, margin, margin, 0 ); setContextMenuPolicy( Qt::NoContextMenu ); d_zoomer[0] = new Zoomer( QwtPlot::xBottom, QwtPlot::yLeft, d_plot->canvas() ); d_zoomer[0]->setRubberBand( QwtPicker::RectRubberBand ); d_zoomer[0]->setRubberBandPen( QColor( Qt::green ) ); d_zoomer[0]->setTrackerMode( QwtPicker::ActiveOnly ); d_zoomer[0]->setTrackerPen( QColor( Qt::white ) ); d_zoomer[1] = new Zoomer( QwtPlot::xTop, QwtPlot::yRight, d_plot->canvas() ); d_panner = new QwtPlotPanner( d_plot->canvas() ); d_panner->setMouseButton( Qt::MidButton ); d_picker = new QwtPlotPicker( QwtPlot::xBottom, QwtPlot::yLeft, QwtPlotPicker::CrossRubberBand, QwtPicker::AlwaysOn, d_plot->canvas() ); d_picker->setStateMachine( new QwtPickerDragPointMachine() ); d_picker->setRubberBandPen( QColor( Qt::green ) ); d_picker->setRubberBand( QwtPicker::CrossRubberBand ); d_picker->setTrackerPen( QColor( Qt::white ) ); setCentralWidget( d_plot ); QToolBar *toolBar = new QToolBar( this ); QToolButton *btnZoom = new QToolButton( toolBar ); btnZoom->setText( "Zoom" ); btnZoom->setIcon( QPixmap( zoom_xpm ) ); btnZoom->setCheckable( true ); btnZoom->setToolButtonStyle( Qt::ToolButtonTextUnderIcon ); toolBar->addWidget( btnZoom ); connect( btnZoom, SIGNAL( toggled( bool ) ), SLOT( enableZoomMode( bool ) ) ); #ifndef QT_NO_PRINTER QToolButton *btnPrint = new QToolButton( toolBar ); btnPrint->setText( "Print" ); btnPrint->setIcon( QPixmap( print_xpm ) ); btnPrint->setToolButtonStyle( Qt::ToolButtonTextUnderIcon ); toolBar->addWidget( btnPrint ); connect( btnPrint, SIGNAL( clicked() ), SLOT( print() ) ); #endif QToolButton *btnExport = new QToolButton( toolBar ); btnExport->setText( "Export" ); btnExport->setIcon( QPixmap( print_xpm ) ); btnExport->setToolButtonStyle( Qt::ToolButtonTextUnderIcon ); toolBar->addWidget( btnExport ); connect( btnExport, SIGNAL( clicked() ), SLOT( exportDocument() ) ); toolBar->addSeparator(); QWidget *hBox = new QWidget( toolBar ); QHBoxLayout *layout = new QHBoxLayout( hBox ); layout->setSpacing( 0 ); layout->addWidget( new QWidget( hBox ), 10 ); // spacer layout->addWidget( new QLabel( "Damping Factor", hBox ), 0 ); layout->addSpacing( 10 ); QwtCounter *cntDamp = new QwtCounter( hBox ); cntDamp->setRange( 0.0, 5.0, 0.01 ); cntDamp->setValue( 0.0 ); layout->addWidget( cntDamp, 0 ); ( void )toolBar->addWidget( hBox ); addToolBar( toolBar ); #ifndef QT_NO_STATUSBAR ( void )statusBar(); #endif enableZoomMode( false ); showInfo(); connect( cntDamp, SIGNAL( valueChanged( double ) ), d_plot, SLOT( setDamp( double ) ) ); connect( d_picker, SIGNAL( moved( const QPoint & ) ), SLOT( moved( const QPoint & ) ) ); connect( d_picker, SIGNAL( selected( const QPolygon & ) ), SLOT( selected( const QPolygon & ) ) ); }
FilterWindow::FilterWindow() { id = 0; QToolBar *toolBar = new QToolBar(this); QToolBar *lowerToolBar = new QToolBar(this); //lowerToolBar->setFixedHeight(80); toolBar->setFixedHeight(80); #if QT_VERSION < 0x040000 setDockEnabled(TornOff, true); setRightJustification(true); #else toolBar->setAllowedAreas(Qt::TopToolBarArea | Qt::BottomToolBarArea); lowerToolBar->setAllowedAreas(Qt::BottomToolBarArea); #endif QWidget *hBox = new QWidget(toolBar); QWidget *lowerBox = new QWidget(lowerToolBar); QLabel *label = new QLabel("Frequency", hBox); QLabel *clabel = new QLabel("Range Max", hBox); QLabel *mlabel = new QLabel("Range Min", hBox); QwtCounter *counter = new QwtCounter(hBox); QwtCounter *rangeCounter = new QwtCounter(hBox); QwtCounter *minCounter = new QwtCounter(hBox); QPushButton *scaleButton = new QPushButton("&Autoscale", hBox); QPushButton *mgxButton = new QPushButton("MG&x", lowerBox); QPushButton *avgButton = new QPushButton("Local Avg", lowerBox); QPushButton *eButton = new QPushButton("e", lowerBox); QPushButton *fButton = new QPushButton("f[n]", lowerBox); QPushButton *mavgButton = new QPushButton("Moving Avg", lowerBox); QwtKnob *rcKnob = new QwtKnob(lowerBox); rcKnob->setRange(0,5,.1,0); rcKnob->setScaleMaxMajor(10); rcKnob->setValue(5.0); QLabel *rcLabel = new QLabel("RC", rcKnob); rcLabel->setAlignment(Qt::AlignTop | Qt::AlignHCenter); QwtKnob *dtKnob = new QwtKnob(lowerBox); dtKnob->setRange(0,5,.1,0); dtKnob->setScaleMaxMajor(10); dtKnob->setValid(1.0); QLabel *dtLabel = new QLabel("Dt", dtKnob); dtLabel->setAlignment(Qt::AlignTop | Qt::AlignHCenter); QwtKnob *duKnob = new QwtKnob(lowerBox); duKnob->setRange(0,5000,10,1); duKnob->setScaleMaxMajor(10); duKnob->setValid(1.0); QLabel *duLabel = new QLabel("Du", duKnob); duLabel->setAlignment(Qt::AlignTop | Qt::AlignHCenter); // Sets the range and increment of the widgets counter->setRange(-1.0, 2000.0, 10.0); rangeCounter->setRange(-1048576.0,INT_MAX,100.0); minCounter->setRange(-1048576.0, INT_MAX, 100.0); QHBoxLayout *layout = new QHBoxLayout(hBox); layout->addWidget(label); layout->addWidget(counter); layout->addWidget(clabel); layout->addWidget(rangeCounter); layout->addWidget(mlabel); layout->addWidget(minCounter); layout->addWidget(scaleButton); QHBoxLayout *lowerLayout = new QHBoxLayout(lowerBox); lowerLayout->addWidget(mgxButton); lowerLayout->addWidget(avgButton); lowerLayout->addWidget(eButton); lowerLayout->addWidget(fButton); lowerLayout->addWidget(mavgButton); lowerLayout->addWidget(rcKnob); lowerLayout->addWidget(dtKnob); lowerLayout->addWidget(duKnob); // layout->addWidget(new QWidget(hBox), 10); // spacer); #if QT_VERSION >= 0x040000 toolBar->addWidget(hBox); lowerToolBar->addWidget(lowerBox); #endif addToolBar(toolBar); // Instantiates the plot, this being the parent widget plot = new FilteredDataPlot(this); setCentralWidget(plot); addToolBarBreak(Qt::TopToolBarArea); addToolBar(lowerToolBar); // Connect signals connect(counter, SIGNAL(valueChanged(double)), plot, SLOT(setTimerInterval(double)) ); connect(rangeCounter, SIGNAL(valueChanged(double)), plot, SLOT(setRange(double))); connect(minCounter, SIGNAL(valueChanged(double)), plot, SLOT(setMinRange(double))); connect(mgxButton, SIGNAL(clicked()), plot, SLOT(detachMgx())); connect(avgButton, SIGNAL(clicked()), plot, SLOT(detachAvg())); connect(eButton,SIGNAL(clicked()), plot, SLOT(detachE())); connect(fButton, SIGNAL(clicked()), plot, SLOT(detachF())); connect(mavgButton, SIGNAL(clicked()), plot, SLOT(detachMavg())); connect(scaleButton, SIGNAL(clicked()), plot, SLOT(autoScale())); connect(scaleButton, SIGNAL(clicked()), plot->getDataFilter(), SLOT(resetLocalMax())); connect(rcKnob, SIGNAL(valueChanged(double)), plot->getDataFilter(), SLOT(setRc(double)) ); connect(dtKnob, SIGNAL(valueChanged(double)), plot->getDataFilter(), SLOT(setDt(double)) ); connect(duKnob, SIGNAL(valueChanged(double)), plot->getDataFilter(), SLOT(setU(double))); counter->setValue(50.0); rangeCounter->setValue(10000.0); minCounter->setValue(2000); }