int main(int argv, char **args)
{
    QApplication app(argv, args);
    app.setApplicationName("Volume slider tester");

    Phonon::MediaObject *mediaObject = new Phonon::MediaObject;
    mediaObject->setCurrentSource(QString("/home/gvatteka/Music/Lumme-Badloop.ogg"));

//! [0]
    Phonon::AudioOutput *audioOutput = new Phonon::AudioOutput(Phonon::MusicCategory);
    Phonon::createPath(mediaObject, audioOutput);

    Phonon::VolumeSlider *volumeSlider = new Phonon::VolumeSlider;
    volumeSlider->setAudioOutput(audioOutput);
//! [0]

    mediaObject->play();
    
    volumeSlider->show();

    return app.exec();
}
// 初始化播放器
void MyWidget::initPlayer()
{
    // 设置主界面标题、图标和大小
    setWindowTitle(tr("MyPlayer音乐播放器"));
    setWindowIcon(QIcon(":/images/icon.png"));
    setMinimumSize(320, 160);
    setMaximumSize(320, 160);

    // 创建媒体图
    mediaObject = new Phonon::MediaObject(this);
    Phonon::AudioOutput *audioOutput = new Phonon::AudioOutput(Phonon::MusicCategory, this);
    Phonon::createPath(mediaObject, audioOutput);

    // 关联媒体对象的tick()信号来更新播放时间的显示
    connect(mediaObject, SIGNAL(tick(qint64)), this, SLOT(updateTime(qint64)));

    // 创建顶部标签,用于显示一些信息
    topLabel = new QLabel(tr("<a href = \" http://www.yafeilinux.com \"> www.yafeilinux.com </a>"));
    topLabel->setTextFormat(Qt::RichText);
    topLabel->setOpenExternalLinks(true);
    topLabel->setAlignment(Qt::AlignCenter);

    // 创建控制播放进度的滑块
    Phonon::SeekSlider *seekSlider = new Phonon::SeekSlider(mediaObject, this);

    // 创建包含播放列表图标、显示时间标签和桌面歌词图标的工具栏
    QToolBar *widgetBar = new QToolBar(this);
    // 显示播放时间的标签
    timeLabel = new QLabel(tr("00:00 / 00:00"), this);
    timeLabel->setToolTip(tr("当前时间 / 总时间"));
    timeLabel->setAlignment(Qt::AlignCenter);
    timeLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
    // 创建图标,用于控制是否显示播放列表
    QAction *PLAction = new QAction(tr("PL"), this);
    PLAction->setShortcut(QKeySequence("F4"));
    PLAction->setToolTip(tr("播放列表(F4)"));
    connect(PLAction, SIGNAL(triggered()), this, SLOT(setPlaylistShown()));
    // 创建图标,用于控制是否显示桌面歌词
    QAction *LRCAction = new QAction(tr("LRC"), this);
    LRCAction->setShortcut(QKeySequence("F2"));
    LRCAction->setToolTip(tr("桌面歌词(F2)"));
    connect(LRCAction, SIGNAL(triggered()), this, SLOT(setLrcShown()));
    // 添加到工具栏
    widgetBar->addAction(PLAction);
    widgetBar->addSeparator();
    widgetBar->addWidget(timeLabel);
    widgetBar->addSeparator();
    widgetBar->addAction(LRCAction);

    // 创建播放控制动作工具栏
    QToolBar *toolBar = new QToolBar(this);
    // 播放动作
    playAction = new QAction(this);
    playAction->setIcon(QIcon(":/images/play.png"));
    playAction->setText(tr("播放(F5)"));
    playAction->setShortcut(QKeySequence(tr("F5")));
    connect(playAction, SIGNAL(triggered()), this, SLOT(setPaused()));
    // 停止动作
    stopAction = new QAction(this);
    stopAction->setIcon(QIcon(":/images/stop.png"));
    stopAction->setText(tr("停止(F6)"));
    stopAction->setShortcut(QKeySequence(tr("F6")));
    connect(stopAction, SIGNAL(triggered()), mediaObject, SLOT(stop()));
    // 跳转到上一首动作
    skipBackwardAction = new QAction(this);
    skipBackwardAction->setIcon(QIcon(":/images/skipBackward.png"));
    skipBackwardAction->setText(tr("上一首(Ctrl+Left)"));
    skipBackwardAction->setShortcut(QKeySequence(tr("Ctrl+Left")));
    connect(skipBackwardAction, SIGNAL(triggered()), this, SLOT(skipBackward()));
    // 跳转到下一首动作
    skipForwardAction = new QAction(this);
    skipForwardAction->setIcon(QIcon(":/images/skipForward.png"));
    skipForwardAction->setText(tr("下一首(Ctrl+Right)"));
    skipForwardAction->setShortcut(QKeySequence(tr("Ctrl+Right")));
    connect(skipForwardAction, SIGNAL(triggered()), this, SLOT(skipForward()));
    // 打开文件动作
    QAction *openAction = new QAction(this);
    openAction->setIcon(QIcon(":/images/open.png"));
    openAction->setText(tr("播放文件(Ctrl+O)"));
    openAction->setShortcut(QKeySequence(tr("Ctrl+O")));
    connect(openAction, SIGNAL(triggered()), this, SLOT(openFile()));
    // 音量控制部件
    Phonon::VolumeSlider *volumeSlider = new Phonon::VolumeSlider(audioOutput, this);
    volumeSlider->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
    // 添加到工具栏
    toolBar->addAction(playAction);
    toolBar->addSeparator();
    toolBar->addAction(stopAction);
    toolBar->addSeparator();
    toolBar->addAction(skipBackwardAction);
    toolBar->addSeparator();
    toolBar->addAction(skipForwardAction);
    toolBar->addSeparator();
    toolBar->addWidget(volumeSlider);
    toolBar->addSeparator();
    toolBar->addAction(openAction);

    // 创建主界面布局管理器
    QVBoxLayout *mainLayout = new QVBoxLayout;
    mainLayout->addWidget(topLabel);
    mainLayout->addWidget(seekSlider);
    mainLayout->addWidget(widgetBar);
    mainLayout->addWidget(toolBar);
    setLayout(mainLayout);

    // 在3-2中添加的代码
    connect(mediaObject, SIGNAL(stateChanged(Phonon::State, Phonon::State)),
            this, SLOT(stateChanged(Phonon::State, Phonon::State)));

    // 以下是在3-3中添加的代码

    // 创建播放列表
    playlist = new MyPlaylist(this);
    connect(playlist, SIGNAL(cellClicked(int, int)), this, SLOT(tableClicked(int)));
    connect(playlist, SIGNAL(playlistClean()), this, SLOT(clearSources()));

    // 创建用来解析媒体的信息的元信息解析器
    metaInformationResolver = new Phonon::MediaObject(this);
    // 需要与AudioOutput连接后才能使用metaInformationResolver来获取歌曲的总时间
    Phonon::AudioOutput *metaInformationAudioOutput =
            new Phonon::AudioOutput(Phonon::MusicCategory, this);
    Phonon::createPath(metaInformationResolver, metaInformationAudioOutput);
    connect(metaInformationResolver, SIGNAL(stateChanged(Phonon::State, Phonon::State)),
            this, SLOT(metaStateChanged(Phonon::State, Phonon::State)));

    connect(mediaObject, SIGNAL(currentSourceChanged(Phonon::MediaSource)),
            this, SLOT(sourceChanged(Phonon::MediaSource)));
    connect(mediaObject, SIGNAL(aboutToFinish()), this, SLOT(aboutToFinish()));

    // 初始化动作图标的状态
    playAction->setEnabled(false);
    stopAction->setEnabled(false);
    skipBackwardAction->setEnabled(false);
    skipForwardAction->setEnabled(false);
    topLabel->setFocus();

}
Example #3
0
Player::Player(QWidget *parent) : KXmlGuiWindow(parent) {
	//SETUP DATABASE
	QDir(KGlobal::dirs()->saveLocation("data")).mkdir("projekt7"); //NOTE: creates the projekt7 directory if it doesn't already exist
	QString db_path = KGlobal::dirs()->saveLocation("data") + "projekt7/tracks_db";
	int return_code = sqlite3_open(qtos(db_path), &tracks_db);
	if (return_code) {
		showError("Failed to open the Projekt7 Track Database: ", sqlite3_errmsg(tracks_db));
		exit(return_code);
	}
	const char *create_table = "CREATE TABLE IF NOT EXISTS `tracks` (`tid` INTEGER PRIMARY KEY, `artist` VARCHAR KEY ASC, `year` INT KEY ASC, `album` VARCHAR, `track_number` INT KEY ASC, `title` VARCHAR, `path` VARCHAR, `length` INT, `playcount` INT)"; //TODO make use of the `length` and `playcount` columns
	char *errmsg;
	return_code = sqlite3_exec(tracks_db, create_table, 0, 0, &errmsg);
	if (return_code) {
		showError("Failed to create `tracks` table: ", errmsg);
		sqlite3_free(errmsg);
		exit(return_code);
	}
	updateNumTracks();
	
	//SETUP PHONON
	now_playing = new Phonon::MediaObject(this);
	Phonon::AudioOutput *audioOutput = new Phonon::AudioOutput(Phonon::MusicCategory, this);
	createPath(now_playing, audioOutput);
	now_playing->setTickInterval(1000);
	
	//SETUP WIDGETS
	QWidget *central_widget = new QWidget(this);
	KToolBar *toolbar_widget = new KToolBar(i18n("Main Toolbar"), central_widget);
	toolbar_widget->setIconDimensions(32);
	playlist_widget = new QWidget(central_widget);
	artist_list = new KListWidget(playlist_widget);
	artist_list->addItem(ALL);
	album_list = new KListWidget(playlist_widget);
	titles_list = new KListWidget(playlist_widget);
	QAction* tb_previousAction = toolbar_widget->addAction(KIcon("media-skip-backward"), "");
	QString previousHelpText = i18n("Play the previous track");
	tb_previousAction->setToolTip(previousHelpText);
	QAction* tb_pauseAction = toolbar_widget->addAction(KIcon("media-playback-pause"), "");
	QString plauseHelpText = i18n("Plause playback");
	tb_pauseAction->setToolTip(plauseHelpText);
	QAction* tb_playAction = toolbar_widget->addAction(KIcon("media-playback-start"), "");
	QString playHelpText = i18n("Play the track");
	tb_playAction->setToolTip(playHelpText);
	QAction* tb_nextAction = toolbar_widget->addAction(KIcon("media-skip-forward"), "");
	QString nextHelpText = i18n("Play the next track");
	tb_nextAction->setToolTip(nextHelpText);
	toolbar_widget->addSeparator();
	Phonon::VolumeSlider *volumeSlider = new Phonon::VolumeSlider;
	volumeSlider->setAudioOutput(audioOutput);
	volumeSlider->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Fixed);
	toolbar_widget->addWidget(volumeSlider);
	toolbar_widget->addSeparator();
	Phonon::SeekSlider *seekSlider = new Phonon::SeekSlider(now_playing);
	volumeSlider->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
	toolbar_widget->addWidget(seekSlider);
	toolbar_widget->addSeparator();
	cur_time = new QLabel(" 0:00", toolbar_widget);
	cur_time->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Fixed);
	toolbar_widget->addWidget(cur_time);
	toolbar_widget->addWidget(new QLabel(" / ", toolbar_widget));
	track_duration = new QLabel("0:00", toolbar_widget);
	track_duration->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Fixed);
	toolbar_widget->addWidget(track_duration);
	queued = new KIcon("go-next-view");
	
	QHBoxLayout *listLayout = new QHBoxLayout;
	listLayout->addWidget(artist_list);
	listLayout->addWidget(album_list);
	listLayout->addWidget(titles_list);
	playlist_widget->setLayout(listLayout);
	
	QVBoxLayout *mainLayout = new QVBoxLayout;
	mainLayout->addWidget(toolbar_widget);
	mainLayout->addWidget(playlist_widget);
	central_widget->setLayout(mainLayout);
	
	setCentralWidget(central_widget);
	
	//SETUP STATUS BAR
	KStatusBar* bar = statusBar();
	bar->insertPermanentItem("", SONG_NAME, true);
	bar->setItemAlignment(SONG_NAME, Qt::AlignLeft | Qt::AlignVCenter);
	
	//SETUP SYSTEM TRAY ICON
	tray_icon = new KSystemTrayIcon("projekt7", this);
	tray_icon->show();
	
	//SETUP METADATA WINDOW
	metadata_window = new QWidget(this, Qt::Dialog);
	metadata_window->setWindowModality(Qt::WindowModal);
	metadata_window->setWindowTitle("Track Details  |  Projekt 7");
	mw_ok_button = new KPushButton(KIcon("dialog-ok-apply"), "OK", metadata_window);
	mw_ok_button->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Fixed);
	
	QGridLayout *mwLayout = new QGridLayout;
	mwLayout->addWidget(new QLabel("Artist:",        metadata_window), 0, 0);
	mwLayout->addWidget(new QLabel("Year:",          metadata_window), 1, 0);
	mwLayout->addWidget(new QLabel("Album:",         metadata_window), 2, 0);
	mwLayout->addWidget(new QLabel("Track Number:",  metadata_window), 3, 0);
	mwLayout->addWidget(new QLabel("Title:",         metadata_window), 4, 0);
	mwLayout->addWidget(new QLabel("File Path:",     metadata_window), 5, 0);
	mwLayout->addWidget(mw_artist       = new QLabel(metadata_window), 0, 1);
	mwLayout->addWidget(mw_year         = new QLabel(metadata_window), 1, 1);
	mwLayout->addWidget(mw_album        = new QLabel(metadata_window), 2, 1);
	mwLayout->addWidget(mw_track_number = new QLabel(metadata_window), 3, 1);
	mwLayout->addWidget(mw_title        = new QLabel(metadata_window), 4, 1);
	mwLayout->addWidget(mw_path         = new QLabel(metadata_window), 5, 1);
	mwLayout->addWidget(mw_ok_button, 6, 0, 1, 2, Qt::AlignCenter);
	metadata_window->setLayout(mwLayout);
	
	//SETUP QUEUE EDITOR WINDOW
	queue_window = new QWidget(this, Qt::Dialog);
	queue_window->setWindowModality(Qt::WindowModal);
	queue_window->setWindowTitle("Track Queue Editor  |  Projekt 7");
	qw_ok_button = new KPushButton(KIcon("dialog-ok-apply"), "OK", queue_window);
	qw_ok_button->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Fixed);
	
	QVBoxLayout *qw_buttons_layout = new QVBoxLayout;
	KPushButton *qw_top_button     = new KPushButton(KIcon("go-top"),      "", queue_window);
	KPushButton *qw_up_button      = new KPushButton(KIcon("go-up"),       "", queue_window);
	KPushButton *qw_down_button    = new KPushButton(KIcon("go-down"),     "", queue_window);
	KPushButton *qw_bottom_button  = new KPushButton(KIcon("go-bottom"),   "", queue_window);
	KPushButton *qw_remove_button  = new KPushButton(KIcon("edit-delete"), "", queue_window);
	qw_buttons_layout->addWidget(qw_top_button);
	qw_buttons_layout->addWidget(qw_up_button);
	qw_buttons_layout->addWidget(qw_down_button);
	qw_buttons_layout->addWidget(qw_bottom_button);
	qw_buttons_layout->addWidget(qw_remove_button);
	
	QHBoxLayout *qw_list_buttons_layout = new QHBoxLayout;
	qw_queue_list = new KListWidget(queue_window);
	QWidget *qw_button_holder = new QWidget(queue_window);
	qw_button_holder->setLayout(qw_buttons_layout);
	qw_list_buttons_layout->addWidget(qw_queue_list);
	qw_list_buttons_layout->addWidget(qw_button_holder);
	
	QVBoxLayout *qwLayout = new QVBoxLayout;
	QWidget *qw_list_buttons = new QWidget(queue_window);
	qw_list_buttons->setLayout(qw_list_buttons_layout);
	qwLayout->addWidget(qw_list_buttons);
	qwLayout->addWidget(qw_ok_button, 0, Qt::AlignCenter);
	queue_window->setLayout(qwLayout);
	
	//SETUP ACTIONS
 	KStandardAction::quit(kapp, SLOT(quit()), actionCollection());
	connect(kapp, SIGNAL(aboutToQuit()), this, SLOT(quit()));
	connect(now_playing, SIGNAL(aboutToFinish()), this, SLOT(enqueueNext()));
	connect(now_playing, SIGNAL(totalTimeChanged(qint64)), this, SLOT(updateDuration(qint64)));
	connect(now_playing, SIGNAL(tick(qint64)), this, SLOT(tick(qint64)));
	KAction *openFilesAction = setupKAction("document-open", i18n("Open"), i18n("Load the selected files"), "files");
	openFilesAction->setShortcut(QKeySequence::Open);
	connect(openFilesAction, SIGNAL(triggered(bool)), this, SLOT(loadFiles()));
	KAction *openDirectoryAction = setupKAction("document-open-folder", i18n("Open Directory..."), i18n("Load all files in the selected directory and its subdirectories"), "directory");
	openDirectoryAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_D));
	connect(openDirectoryAction, SIGNAL(triggered(bool)), this, SLOT(loadDirectory()));
	KAction *previousAction = setupKAction("media-skip-backward", i18n("Previous"), previousHelpText, "previous");
	previousAction->setShortcut(QKeySequence(Qt::Key_Z));
	connect(previousAction, SIGNAL(triggered(bool)), this, SLOT(previous()));
	connect(tb_previousAction, SIGNAL(triggered(bool)), this, SLOT(previous()));
	KAction *pauseAction = setupKAction("media-playback-pause", i18n("Pause"), plauseHelpText, "pause");
	pauseAction->setShortcut(QKeySequence(Qt::Key_C));
	connect(pauseAction, SIGNAL(triggered(bool)), this, SLOT(pause()));
	connect(tb_pauseAction, SIGNAL(triggered(bool)), this, SLOT(pause()));
	KAction *playAction = setupKAction("media-playback-start", i18n("Play"), playHelpText, "play");
	playAction->setShortcut(QKeySequence(Qt::Key_X));
	connect(playAction, SIGNAL(triggered(bool)), this, SLOT(play()));
	connect(tb_playAction, SIGNAL(triggered(bool)), this, SLOT(play()));
	KAction *nextAction = setupKAction("media-skip-forward", i18n("Next"), nextHelpText, "next");
	nextAction->setShortcut(QKeySequence(Qt::Key_V));
	connect(nextAction, SIGNAL(triggered(bool)), this, SLOT(next()));
	connect(tb_nextAction, SIGNAL(triggered(bool)), this, SLOT(next()));
	KAction *queueAction = setupKAction("go-next-view", i18n("Queue Track"), "Enqueue the current track", "queue");
	queueAction->setShortcut(QKeySequence(Qt::Key_Q));
	connect(queueAction, SIGNAL(triggered(bool)), this, SLOT(queue()));
	shuffleAction = setupKAction("media-playlist-shuffle", i18n("Suffle"), "The next track will be random when checked", "shuffle");
	shuffleAction->setCheckable(true);
	connect(shuffleAction, SIGNAL(triggered(bool)), this, SLOT(shuffle(bool)));
	KAction *viewCurrentTrackAction = setupKAction("go-last", i18n("Current Track"), i18n("Show the Current Track in the Playlist"), "current_track");
	connect(viewCurrentTrackAction, SIGNAL(triggered(bool)), this, SLOT(viewCurrentTrack()));
	KAction *viewTrackDetailsAction = setupKAction("view-media-lyrics", i18n("Track Details"), i18n("View the playing track's metadata"), "track_details");
	connect(viewTrackDetailsAction, SIGNAL(triggered(bool)), this, SLOT(viewTrackDetails()));
	KAction *viewTrackQueueAction = setupKAction("view-time-schedule-edit", i18n("Track Queue"), i18n("Edit the track queue"), "track_queue");
	connect(viewTrackQueueAction, SIGNAL(triggered(bool)), this, SLOT(viewTrackQueue()));
	viewPlaylistAction = setupKAction("view-file-columns", i18n("Playlist"), i18n("Show/Hide the playlist"), "playlist");
	viewPlaylistAction->setCheckable(true);
	connect(viewPlaylistAction, SIGNAL(triggered(bool)), this, SLOT(viewPlaylist(bool)));
	connect(artist_list, SIGNAL(currentItemChanged(QListWidgetItem *, QListWidgetItem *)), this, SLOT(updateAlbumList(QListWidgetItem *,  QListWidgetItem *)));
	connect(album_list,  SIGNAL(currentItemChanged(QListWidgetItem *, QListWidgetItem *)), this, SLOT(updateTitlesList(QListWidgetItem *, QListWidgetItem *)));
	connect(titles_list, SIGNAL(currentItemChanged(QListWidgetItem *, QListWidgetItem *)), this, SLOT(showTrackInfo(QListWidgetItem *,    QListWidgetItem *)));
	connect(titles_list, SIGNAL(itemDoubleClicked(QListWidgetItem *)), this, SLOT(play(QListWidgetItem *)));
	connect(mw_ok_button,     SIGNAL(clicked()), this, SLOT(hideTrackDetails()));
	connect(qw_top_button,    SIGNAL(clicked()), this, SLOT(moveQueuedTrackToTop()));
	connect(qw_up_button,     SIGNAL(clicked()), this, SLOT(moveQueuedTrackUp()));
	connect(qw_down_button,   SIGNAL(clicked()), this, SLOT(moveQueuedTrackDown()));
	connect(qw_bottom_button, SIGNAL(clicked()), this, SLOT(moveQueuedTrackToBottom()));
	connect(qw_remove_button, SIGNAL(clicked()), this, SLOT(dequeueTrack()));
	connect(qw_ok_button,     SIGNAL(clicked()), this, SLOT(hideTrackQueue()));
	
	//SETUP GUI
	qsrand(QDateTime::currentDateTime().toTime_t());
	setupGUI(Default, "projekt7ui.rc");
	updateArtistList(0);
	
	//READ CONFIG
	config = KGlobal::config();
	KConfigGroup curTrackDetails(config, "curTrackDetails");
	cur_artist = artist_list->item(curTrackDetails.readEntry("artist", QString()).toInt());
	cur_album = curTrackDetails.readEntry("album", QString()).toInt();
	cur_title = curTrackDetails.readEntry("title", QString()).toInt();
	KConfigGroup applicationSettings(config, "applicationSettings");
	viewPlaylistAction->setChecked(applicationSettings.readEntry("playlistVisible", QString()).toInt());
	shuffle_tracks = applicationSettings.readEntry("shuffleTracks", QString()).toInt();
	shuffleAction->setChecked(shuffle_tracks);
	viewCurrentTrack();
	if (titles_list->count() > 0) {
		if (titles_list->currentRow() == -1)
			titles_list->setCurrentRow(0);
		play(titles_list->currentItem()->data(Qt::UserRole).toInt(), false, false);
		pause();
		quint64 song_position = curTrackDetails.readEntry("tick", QString()).toLongLong();
		now_playing->seek(song_position);
		tick(song_position);
		//TODO update the seekSlider's position to match the "tick" location of the song
	}
}