首页 > 解决方案 > wxWidgets - 将数据添加到 DataViewListCtrl

问题描述

我正在尝试创建一个用于管理音频样本库的应用程序wxWidgets,我DirCtrl在左侧和DataViewListCtrl右侧有一个,当用户导航到一个文件夹并双击一个文件时,它应该使用提取其标签和音频属性taglib并将它们添加到特定列。我在弄清楚如何将数据添加到DataViewListCtrl我最近在 python 中做了类似的事情时遇到了一些麻烦,而 python 使用 2D 列表向其中添加数据。

应用程序看起来像这样(这是我在 python 中绑定的) 在此处输入图像描述

我必须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 ‘&lt;brace-enclosed initializer list>’ to ‘const value_type&’ {aka ‘const wxVariant&’}
  266 |     Data.push_back({false, Title, Artist, Channels, Length, SampleRate, Bitrate, Comment});
      |                                                                                          ^

标签: c++wxwidgets

解决方案


根据您尝试将数据添加到列表视图的方式,我假设列的设置如下:

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");

尽管 Channels 和 Bitrate 之类的东西是数字,但由于 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 接受文件名,我必须添加一个演员表。


推荐阅读