wxWidgets - 添加数据到 DataViewListCtrl
wxWidgets - Adding data to DataViewListCtrl
我正在尝试使用 wxWidgets
创建一个用于管理音频样本库的应用程序,当用户导航到文件夹并双击文件,它应该使用 taglib
提取其标签和音频属性并将它们添加到特定列。我在弄清楚如何将数据添加到 DataViewListCtrl
时遇到了一些问题 我最近在 python 中做了类似的事情,并且 python 使用了一个二维列表来向其中添加数据。
应用程序看起来像这样(这是我在 python 中整理的)
以及我必须在 C++ 中将数据添加到 DataViewListCtrl
的函数
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
是在同一个 class 中声明的 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});
| ^
根据您尝试将数据添加到列表视图的方式,我假设列设置如下:
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());
行对你有用吗?为了让 TagLib 接受文件名,我必须向 const char*
添加强制转换。
我正在尝试使用 wxWidgets
创建一个用于管理音频样本库的应用程序,当用户导航到文件夹并双击文件,它应该使用 taglib
提取其标签和音频属性并将它们添加到特定列。我在弄清楚如何将数据添加到 DataViewListCtrl
时遇到了一些问题 我最近在 python 中做了类似的事情,并且 python 使用了一个二维列表来向其中添加数据。
应用程序看起来像这样(这是我在 python 中整理的)
以及我必须在 C++ 中将数据添加到 DataViewListCtrl
的函数
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
是在同一个 class 中声明的 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});
| ^
根据您尝试将数据添加到列表视图的方式,我假设列设置如下:
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());
行对你有用吗?为了让 TagLib 接受文件名,我必须向 const char*
添加强制转换。