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* 添加强制转换。