我有一些看起来像这样的代码:
public class PlayerActivity extends Activity
implements SurfaceHolder.Callback {
Uri targetUri;
MediaPlayer mediaPlayer;
SurfaceView surfaceView;
SurfaceHolder surfaceHolder;
boolean pausing = false;
boolean isFirstTime = true;
private SeekBar progressBar;
private FontAwesome fullScreen;
private FontAwesome btnPayPause;
private TextView timeForMediaPlayer;
Timer mTimer;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.playerlayout);
initialize();
targetUri = Uri.parse("http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4");
getWindow().setFormat(PixelFormat.UNKNOWN);
surfaceView = (SurfaceView)findViewById(R.id.surfaceview);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(this);
surfaceHolder.setFixedSize(176, 144);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
mediaPlayer = new MediaPlayer();
mediaPlayer.setScreenOnWhilePlaying(true);
btnPayPause.setOnClickListener(new Button.OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
if (pausing) {
pausing = false;
mediaPlayer.start();
} else {
if (isFirstTime) {
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setDisplay(surfaceHolder);
try {
mediaPlayer.setDataSource(getApplicationContext(), targetUri);
mediaPlayer.prepare();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
mediaPlayer.start();
isFirstTime = false;
} else {
pausing = true;
mediaPlayer.pause();
}
}
}
});
mediaPlayer.setOnBufferingUpdateListener(new MediaPlayer.OnBufferingUpdateListener() {
@Override
public void onBufferingUpdate(MediaPlayer mp, int percent) {
progressBar.setSecondaryProgress(percent);
}
});
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
new Thread(runnable).start();
}
});
progressBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if (mediaPlayer != null && fromUser) {
int timeToSet = (mediaPlayer.getDuration() * progress) / 100;
mediaPlayer.seekTo(timeToSet);
}
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
fullScreen.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
}
});
}
Runnable runnable = new Runnable() {
@Override
public void run() {
while (true) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {}
int currentTime = mediaPlayer.getCurrentPosition();
int percent = ( 100 * currentTime) / mediaPlayer.getDuration();
progressBar.setProgress(percent);
final String timeToShow = String.format("%02d:%02d:%02d", TimeUnit.MILLISECONDS.toHours(currentTime),
TimeUnit.MILLISECONDS.toMinutes(currentTime) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(currentTime)),
TimeUnit.MILLISECONDS.toSeconds(currentTime) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(currentTime)));
runOnUiThread(new Runnable() {
@Override
public void run() {
timeForMediaPlayer.setText(timeToShow);
}
});
}
}
};
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
mediaPlayer.release();
}
@Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
// TODO Auto-generated method stub
}
@Override
public void surfaceCreated(SurfaceHolder arg0) {
// TODO Auto-generated method stub
}
@Override
public void surfaceDestroyed(SurfaceHolder arg0) {
// TODO Auto-generated method stub
}
private void initialize() {
timeForMediaPlayer = (TextView) findViewById(R.id.timeForMediaPlayer);
progressBar = (SeekBar) findViewById(R.id.progressBar);
fullScreen = (FontAwesome) findViewById(R.id.fullScreen);
btnPayPause = (FontAwesome) findViewById(R.id.btnPayPause);
}
}
这很好但我想利用Qt5's new signal/slot syntax(并删除宏)。如果我将connect()更改为:
class MyClass : public QObject
{
Q_OBJECT
signals:
void SetValue(float value);
public slots:
void OnSetValue(float value, bool fromDatabase = false);
}
connect(this, SIGNAL(SetValue(float)), this, SLOT(OnSetValue(float)));
我得到(在Visual Studio 2013中):
错误C2338:插槽需要的参数多于信号提供的参数
我可以创建一个调用OnSetValue()的中间函数,并允许设置默认参数,但这似乎浪费了代码。什么是解决这个问题的更好方法?
答案 0 :(得分:3)
link提供的sim642也表示新的连接语法"可以与c + 11 lambda表达式"一起使用。对于上面的例子,我能够使用:
connect(this, &MyClass::SetValue, [=](float value) { OnSetValue(value); });
稍微复杂但是代码少于添加中间函数,并且仍然提供编译时检查。
Igor Tandetnik提供了更好的版本:
connect(this, &MyClass::SetValue, [this](float value){ OnSetValue(value); });
使用[this]替换[=](使lambda能够按值捕获范围内的所有自动变量),减少lambda的范围和出错的可能性。