0

我创建了一个默认的 Qt GUI 应用程序,我void keyPressEvent(QKeyEvent* ev);在主窗口类中添加了,当用户按下空格时,应用程序会播放声音(ok)但是当用户在短时间内多次按下时,应用程序不会响应。我不知道为什么?请帮帮我!

。轮廓:

QT       += core gui multimedia

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = untitled2
TEMPLATE = app


SOURCES += main.cpp\
        mainwindow.cpp

HEADERS  += mainwindow.h

FORMS    += mainwindow.ui

RESOURCES += \
    res.qrc

主窗口.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QMediaPlayer>

namespace Ui { class MainWindow; }

class MainWindow : public QMainWindow {
  Q_OBJECT
public:
  explicit MainWindow(QWidget *parent = 0);
  ~MainWindow();
  void keyPressEvent(QKeyEvent* ev);
private:
  Ui::MainWindow *ui;
  QMediaPlayer mp;
};

#endif // MAINWINDOW_H

主窗口.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QKeyEvent>

MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow)
{ ui->setupUi(this); }

MainWindow::~MainWindow() { delete ui; }

void MainWindow::keyPressEvent(QKeyEvent* ev) {
  switch(ev->key()) {
  case Qt::Key_Space: {
    mp.setMedia(QUrl("qrc:/sounds/Fireworks.wav"));
    mp.play();
    break;
  }
  }
}

主文件

#include "mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
  QApplication a(argc, argv);
  MainWindow w;
  w.show();
  return a.exec();
}

(注:我这里确实上传了mainwindow.ui.res.qrc)

4

3 回答 3

1

mp.setMedia(QUrl("qrc:/sounds/Fireworks.wav"));

不要不必要地设置媒体,因为媒体播放器不会在内部检查“哦,媒体是一样的,我要聪明点”

相反,您希望在再次按下其键时从头开始启动媒体。最简单的解决方案是使用一个布尔值来指示是否设置了媒体。

  case Qt::Key_Space: 
  {
    if(!is_media_set)
    {
        mp.setMedia(QUrl("qrc:/sounds/Fireworks.wav"));
        is_media_set = true;
    }
    mp.setPosition(0);
    mp.play();
    break;
  }

If several keys trigger different sounds replace the boolean with current_media_key to indicate the last media loaded.

于 2015-09-10T07:47:32.990 回答
1

To setMedia, the documentation says:

Setting this property to a null QMediaContent will cause the player to discard all information relating to the current media source and to cease all I/O operations related to that media.

Each time one presses space again, the media file has to be loaded from disk, it might be a good idea to load it once in the constructor or an initialization method, to save the loading time (access to a hard disk is always slow)

To run the sound again, add also setPosition(0) before calling play().

于 2015-09-10T07:50:46.523 回答
0

I'm not sure this is the best answer, but this is my final result:

void MainWindow::keyPressEvent(QKeyEvent* ev) {
  switch(ev->key()) {
  case Qt::Key_Space: {
    qDebug() << mp.mediaStatus() << mp.state();
    if(mp.state() == QMediaPlayer::StoppedState) {
      mp.setMedia(QUrl("qrc:/sounds/Fireworks.wav"));
    }
    mp.setPosition(0);
    mp.play();
    break;
  }
  }
}
于 2015-09-10T09:11:12.777 回答