Я пытаюсь создать приложение для управления библиотекой аудиосэмплов с помощью wxWidgets
, у меня есть DirCtrl
слева и DataViewListCtrl
справа, когда пользователь переходит к папке и дважды щелкает файл, он должен извлекать его теги и свойства звука, используя taglib
и добавить их в определенные столбцы. У меня возникли проблемы с выяснением того, как добавить данные в DataViewListCtrl
Недавно я сделал что-то подобное в python, и python использовал 2D-список, чтобы добавить в него данные.
Приложение выглядит так (это от того, что я связал его на питоне)
И функция, которую я должен добавить в DataViewListCtrl
в C++
void Browser::OnClickDirCtrl(wxCommandEvent& event)
{
TagLib::FileRef File (DirCtrl->GetFilePath());
TagLib::String Artist = File.tag()->artist();
TagLib::String Album = File.tag()->album();
TagLib::String Genre = File.tag()->genre();
TagLib::String Title = File.tag()->title();
TagLib::String Comment = File.tag()->comment();
int Bitrate = File.audioProperties()->bitrate();
int Channels = File.audioProperties()->channels();
int Length = File.audioProperties()->lengthInMilliseconds();
int LengthSec = File.audioProperties()->lengthInSeconds();
int SampleRate = File.audioProperties()->sampleRate();
std::cout << "Artist: " << Artist << std::endl;
std::cout << "Album: "<< Album << std::endl;
std::cout << "Genre:" << Genre << std::endl;
std::cout << "Title: " << Title << std::endl;
std::cout << "Comment: " << Comment << std::endl;
std::cout << "Bitrate: " << Bitrate << std::endl;
std::cout << "Channels: " << Channels << std::endl;
std::cout << "Length: " << Length << std::endl;
std::cout << "Length in seconds: " << LengthSec << std::endl;
std::cout << "Sample rate: " << SampleRate << std::endl;
std::vector<DataView> Data;
// wxVector<wxVariant> Data;
Data.clear();
// Data.push_back(Artist);
Data.push_back({false, Title, Artist, Channels, Length, SampleRate, Bitrate, Comment});
}
Где DataView
— это struct
, объявленный внутри того же класса.
struct DataView
{
bool Fav;
TagLib::String Title;
TagLib::String Artist;
int Channel;
int Length;
int SampleRate;
int Bitrate;
TagLib::String Comment;
};
Но я получаю сообщение об ошибке при попытке построить это высказывание
../src/Browser.cpp: In member function ‘void Browser::OnClickDirCtrl(wxCommandEvent&)’:
../src/Browser.cpp:267:32: error: cannot convert ‘std::vector<Browser::DataView>’ to ‘const wxVector<wxVariant>&’
267 | SampleListView->AppendItem(Data);
| ^~~~
| |
| std::vector<Browser::DataView>
Но если я попытаюсь использовать вместо этого wxVector<wxVariant>
, я получу сообщение об ошибке
../src/Browser.cpp: In member function ‘void Browser::OnClickDirCtrl(wxCommandEvent&)’:
../src/Browser.cpp:266:90: error: cannot convert ‘<brace-enclosed initializer list>’ to ‘const value_type&’ {aka ‘const wxVariant&’}
266 | Data.push_back({false, Title, Artist, Channels, Length, SampleRate, Bitrate, Comment});
| ^
Извините, но образцы wxWidget слишком длинные, некоторые из них содержат более 2000+ строк кода. Примеры действительно должны быть короткими и лаконичными.
Основываясь на том, как вы пытаетесь добавить данные в представление списка, я предполагаю, что столбцы были настроены примерно так:
m_dataViewListCtrl->AppendToggleColumn("Fav");
m_dataViewListCtrl->AppendTextColumn("Title");
m_dataViewListCtrl->AppendTextColumn("Artist");
m_dataViewListCtrl->AppendTextColumn("Channels");
m_dataViewListCtrl->AppendTextColumn("Length");
m_dataViewListCtrl->AppendTextColumn("SampleRate");
m_dataViewListCtrl->AppendTextColumn("Bitrate");
m_dataViewListCtrl->AppendTextColumn("Comment");
Несмотря на то, что такие вещи, как каналы и битрейт, являются числами, поскольку wxDataViewListCtrl предлагает только несколько типов столбцов, я предполагаю, что использовался текст. Я также использую m_dataViewListCtrl
для имени элемента управления. Не забудьте изменить его на имя, которое вы используете.
Чтобы добавить данные в элемент управления, вам сначала понадобится служебная функция для преобразования строк TagLib в wxStrings.
wxString TagLibTowx(const TagLib::String& in)
{
return wxString::FromUTF8(in.toCString(true));
}
Затем, чтобы добавить данные в элемент управления, вы должны сделать что-то вроде этого:
void Browser::OnClickDirCtrl(wxCommandEvent& event)
{
TagLib::FileRef File (DirCtrl->GetFilePath());
TagLib::String Artist = File.tag()->artist();
TagLib::String Title = File.tag()->title();
TagLib::String Comment = File.tag()->comment();
int Bitrate = File.audioProperties()->bitrate();
int Channels = File.audioProperties()->channels();
int LengthSec = File.audioProperties()->lengthInSeconds();
int SampleRate = File.audioProperties()->sampleRate();
wxVector<wxVariant> data;
data.push_back(false);
data.push_back(TagLibTowx(Title));
data.push_back(TagLibTowx(Artist));
data.push_back(wxString::Format("%d",Channels));
data.push_back(wxString::Format("%d",LengthSec));
data.push_back(wxString::Format("%d",SampleRate));
data.push_back(wxString::Format("%d",Bitrate));
data.push_back(TagLibTowx(Comment));
m_dataViewListCtrl->AppendItem(data);
}
Если у вас есть другие столбцы, использующие другие данные, которые вы извлекли из файла, надеюсь, понятно, как настроить это для имеющихся у вас столбцов.
Кстати, у вас работает линия TagLib::FileRef File (DirCtrl->GetFilePath());
? Мне пришлось добавить приведение к const char*
, чтобы заставить TagLib принять имя файла.
Спасибо, это работает. Вы очень хорошо объяснили, :D TagLib::FileRef
работает для меня на данный момент, однако я пробовал это месяц назад, и тогда это не сработало, не могу сказать, что я делал по-другому в то время, но это работает сейчас.
@ apoor569, вы смотрели образец представления данных?