📄 qvfb.cpp
字号:
}void QVFb::skinConfigChosen(int i){ if (i == config->skin->count() - 1) { // Browse... ? QFileDialog dlg(this); dlg.setFileMode(QFileDialog::DirectoryOnly); dlg.setWindowTitle(tr("Load Custom Skin...")); dlg.setFilter(tr("All QVFB Skins (*.skin)")); dlg.setDirectory(QDir::current()); if (dlg.exec() && dlg.selectedFiles().count() == 1) { skinfiles.append(dlg.selectedFiles().first()); i = skinfiles.count(); config->skin->insertItem(i, QFileInfo(skinfiles.last()).baseName()); config->skin->setCurrentIndex(i); } else { i = 0; } } if ( i ) { DeviceSkinParameters parameters; QString readError; if (parameters.read(skinfiles[i-1], DeviceSkinParameters::ReadSizeOnly, &readError)) { chooseSize(parameters.screenSize()); if (parameters.screenDepth) chooseDepth(parameters.screenDepth,QVFbView::ARGBFormat); config->touchScreen->setChecked(!parameters.hasMouseHover); } else { qWarning("%s", qPrintable(readError)); } }}void QVFb::setGamma400(int n){ double g = n/100.0; view->setGamma(config->rslider->value()/100.0*g, config->gslider->value()/100.0*g, config->bslider->value()/100.0*g); updateGammaLabels();}void QVFb::setR400(int n){ double g = n/100.0; view->setGamma(config->rslider->value()/100.0*g, view->gammaGreen(), view->gammaBlue()); updateGammaLabels();}void QVFb::setG400(int n){ double g = n/100.0; view->setGamma(view->gammaRed(), config->gslider->value()/100.0*g, view->gammaBlue()); updateGammaLabels();}void QVFb::setB400(int n){ double g = n/100.0; view->setGamma(view->gammaRed(), view->gammaGreen(), config->bslider->value()/100.0*g); updateGammaLabels();}void QVFb::updateGammaLabels(){ config->rlabel->setText(QString::number(view->gammaRed(),'g',2)); config->glabel->setText(QString::number(view->gammaGreen(),'g',2)); config->blabel->setText(QString::number(view->gammaBlue(),'g',2));}QSize QVFb::sizeHint() const{ return QSize(int(view->displayWidth()*view->zoomH()), int(menuBar()->height()+view->displayHeight()*view->zoomV()));}// =====================================================================AnimationSaveWidget::AnimationSaveWidget(QVFbAbstractView *v) : QWidget((QWidget*)0,0), view(v), recording(false), animation(0), timerId(-1), progressTimerId(-1), recOn(red_on_led_xpm), recOff(red_off_led_xpm), imageNum(0){ // Create the animation record UI dialog QVBoxLayout *vlayout = new QVBoxLayout( this ); QWidget *hbox = new QWidget( this ); vlayout->addWidget(hbox); QHBoxLayout *hlayout = new QHBoxLayout(hbox); recBt = new QPushButton( tr("Record"), hbox ); hlayout->addWidget(recBt); resetBt = new QPushButton( tr("Reset"), hbox ); hlayout->addWidget(resetBt); saveBt = new QPushButton( tr("Save"), hbox ); hlayout->addWidget(saveBt); recBt->setFixedWidth( 100 ); resetBt->setFixedWidth( 100 ); saveBt->setFixedWidth( 100 ); timeDpy = new QLabel( "00:00", hbox ); hlayout->addWidget(timeDpy); recLED = new QLabel( hbox ); hlayout->addWidget(recLED); recLED->setPixmap( recOff ); timeDpy->setMargin( 5 ); connect( recBt, SIGNAL(clicked()), this, SLOT(toggleRecord()) ); connect( resetBt, SIGNAL(clicked()), this, SLOT(reset()) ); connect( saveBt, SIGNAL(clicked()), this, SLOT(save()) ); elapsed = 0; vlayout->setMargin( 5 ); vlayout->setSpacing( 5 ); haveMpeg = detectPpmtoMpegCommand(); mpegSave = new QCheckBox( tr("Save in MPEG format (requires netpbm package installed)"), this ); vlayout->addWidget(mpegSave); mpegSave->setChecked( haveMpeg ); mpegSave->setEnabled( haveMpeg ); savingAsMpeg = haveMpeg; QWidget *hbox2 = new QWidget( this ); vlayout->addWidget(hbox2); QHBoxLayout *hlayout2 = new QHBoxLayout( hbox2 ); statusText = new QLabel( tr("Click record to begin recording."), hbox2 ); hlayout2->addWidget(statusText); progressBar = new QProgressBar( hbox2 ); progressBar->setValue( 0 ); hlayout2->addWidget(progressBar); progressBar->hide();}AnimationSaveWidget::~AnimationSaveWidget(){ // clean up removeTemporaryFiles(); delete animation;}// returns true if we have ppmtompeg command, else returns falsebool AnimationSaveWidget::detectPpmtoMpegCommand(){ // search the PATH for the ppmtompeg command to test we can record to mpeg QStringList paths = QString(::getenv("PATH")).split(":"); for ( int i = 0; i < paths.count(); i++ ) if ( QFile::exists( paths[i] + "/" + "ppmtompeg" ) ) return true; return false;}void AnimationSaveWidget::timerEvent( QTimerEvent *te ){ QString str; // Recording timer if ( te->timerId() == timerId ) { // Add a frame to the animation if ( savingAsMpeg && view ) view->image().save( str.sprintf("/tmp/qvfb_tmp_image_%04d.ppm", imageNum), "PPM"); else if ( animation && view ) animation->appendFrame(view->image());//QPoint(0,0)); imageNum++; // Update the display of number of seconds that have been recorded. int tmMsec = tm.elapsed(); timeDpy->setText( str.sprintf("%02d:%02d", tmMsec/60000, (tmMsec%60000)/1000) ); QObject::timerEvent( te ); // Make the recording LED blink static int tick = 0; static bool on = false; if ( tick > 10 ) { tick = 0; if ( on ) recLED->setPixmap( recOff ); else recLED->setPixmap( recOn ); on = !on; } tick++; } // Saving progress timer if ( te->timerId() == progressTimerId ) { // Parse output log file to work out the encoding progress. QFile f("/tmp/qvfb_tmp_output.log"); f.open(QIODevice::ReadOnly); int largestNum = 0; bool done = false; char buffer[1024]; while ( !f.atEnd() ) { // example of the output log entries // During each frame: // "FRAME 764 (B): I BLOCKS: 0...... // When complete: // "======FRAMES READ: 766" f.readLine(buffer, 1024); str = QString(buffer); if ( str.left(6) == "FRAME " ) { int num = str.mid(6, str.indexOf(QChar(' '), 6) - 6).toInt(); if ( num > largestNum ) largestNum = num; } else if ( str.left(18) == "======FRAMES READ:" ) { done = true; } } f.close(); // Update the progress bar with the frame we are up to progressBar->setValue( largestNum ); // Finished saving if ( done ) { progressBar->hide(); statusText->setText( tr("Finished saving.")); removeTemporaryFiles(); killTimer( progressTimerId ); progressTimerId = -1; reset(); } }}// Takes the saved ppm files and converts them to a mpeg file named filenamevoid AnimationSaveWidget::convertToMpeg(QString filename){ recLED->setPixmap( recOff ); killTimer( timerId ); progressBar->show(); progressBar->setRange( 0, imageNum ); progressBar->setValue( 0 ); // Build parameter file required by ppmtompeg QFile file("/tmp/qvfb_tmp_ppmtompeg.params"); if ( file.open( QIODevice::WriteOnly ) ) { QTextStream t( &file ); t << "PATTERN IBBPBBPBBPBBPBB\n"; t << "OUTPUT " << filename << "\n"; t << "INPUT_DIR /tmp\n"; t << "INPUT\n"; QString str; str = str.sprintf("%04d", imageNum - 1); t << "qvfb_tmp_image_*.ppm [0000-" << str << "]\n"; t << "END_INPUT\n"; t << "BASE_FILE_FORMAT PPM\n"; t << "INPUT_CONVERT *\n"; t << "GOP_SIZE 15\n"; t << "SLICES_PER_FRAME 1\n"; t << "PIXEL HALF\n"; t << "RANGE 5\n"; t << "PSEARCH_ALG LOGARITHMIC\n"; t << "BSEARCH_ALG SIMPLE\n"; t << "IQSCALE 1\n"; t << "PQSCALE 1\n"; t << "BQSCALE 1\n"; t << "REFERENCE_FRAME DECODED\n"; t << "ASPECT_RATIO 1\n"; t << "FRAME_RATE 24\n"; t << "BIT_RATE 64000\n"; // Quality t << "BUFFER_SIZE 2048\n"; } file.close(); // ### can't use QProcess, not in Qt 2.3 // ### but it's certainly in Qt 4! use it? // Execute the ppmtompeg command as a seperate process to do the encoding pid_t pid = ::fork(); if ( !pid ) { // Child process // redirect stdout to log file freopen("/tmp/qvfb_tmp_output.log", "w", stdout); // ppmtompeg tool is from the netpbm package ::execlp("ppmtompeg", "ppmtompeg", "/tmp/qvfb_tmp_ppmtompeg.params", (void *)0); exit(0); } // Update the saving progress bar every 200ms progressTimerId = startTimer( 200 );}// Cleanup temporary files created during creating a mpeg filevoid AnimationSaveWidget::removeTemporaryFiles(){ QString str; for ( int i = 0; i < imageNum; i++ ) QFile::remove( str.sprintf("/tmp/qvfb_tmp_image_%04d.ppm", i) ); QFile::remove("/tmp/qvfb_tmp_ppmtompeg.params"); QFile::remove("/tmp/qvfb_tmp_output.log"); imageNum = 0;}// toggles between recording and paused (usually when record button clicked)void AnimationSaveWidget::toggleRecord(){ if ( recording ) { recLED->setPixmap( recOff ); recBt->setText( tr("Record") ); statusText->setText( tr("Paused. Click record to resume, or save if done.")); killTimer( timerId ); timerId = -1; elapsed = tm.elapsed(); } else { recLED->setPixmap( recOn ); recBt->setText( tr("Pause") ); statusText->setText( tr("Recording...")); tm.start(); if ( elapsed == 0 ) { savingAsMpeg = mpegSave->isChecked(); if ( !savingAsMpeg ) { delete animation; animation = new QAnimationWriter("/tmp/qvfb_tmp_animation.mng","MNG"); animation->setFrameRate(24); if ( view ) animation->appendFrame(view->image()); } } tm = tm.addMSecs(-elapsed); elapsed = 0; timerId = startTimer(1000 / 24); } recording = !recording;}// Reset everything to initial state of not recordingvoid AnimationSaveWidget::reset(){ if ( recording ) { toggleRecord(); statusText->setText( tr("Click record to begin recording.")); removeTemporaryFiles(); } progressBar->setValue( 0 ); timeDpy->setText( "00:00" ); elapsed = 0; imageNum = 0; delete animation; animation = 0;}// Prompt for filename to save to and put animation in that filevoid AnimationSaveWidget::save(){ if ( recording ) toggleRecord(); // pauses statusText->setText( tr("Saving... ")); QString filename; if ( savingAsMpeg ) { filename = QFileDialog::getSaveFileName(this, tr("Save animation..."), "", "*.mpg"); if ( !filename.isNull() ) convertToMpeg(filename); } else { filename = QFileDialog::getSaveFileName(this, tr("Save animation..."), "", "*.mng"); if (filename.isNull()) { statusText->setText(tr("Save canceled.")); } else { QFile::remove(filename); bool success = QFile::rename(QLatin1String("/tmp/qvfb_tmp_animation.mng"), filename); if (success) { statusText->setText(tr("Finished saving.")); reset(); } else { statusText->setText(tr("Save failed!")); } } }}QT_END_NAMESPACE#include "qvfb.moc"
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -