我想要一个列表小部件,它是一个单一目录中的文件的平面视图。它应该是实时监测,理想情况下,我应该能够禁用它自己,暂时更新,如果有很多事情要在短时间内发生。是否有一个标准的小部件可以做到这一点?快速搜索会弹出wxGenericDirCtrl
,但据我所知,它不可能只显示单个目录的文件(而不是目录)。与其说是一张单子,不如说是一棵树。
否则,做类似事情的最好方法是什么。我可能会将wxListBox
子类化,并使用wxFileSystemWatcher
来保持视图的同步,但这将是一件乏味的事情。有更好的办法吗?
我在Windows上;可移植性不是问题。我的目标是Windows 7到10。
发布于 2021-05-22 15:59:25
如前所述,鉴于您所述的要求,我认为除了使用wxFileSystemWatcher
之外,还有其他方法可以做到这一点。
我收集了一个示例,说明如何根据文件系统观察者的报告来更新列表框。我不得不承认,这确实比我想象的要复杂得多,但我不认为这太乏味了。
// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
// for all others, include the necessary headers (this file is usually all you
// need because it includes almost all "standard" wxWidgets headers)
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
#include <wx/fswatcher.h>
#include <wx/filepicker.h>
#include <vector>
class MyFrame: public wxFrame
{
public:
MyFrame();
private:
// Event handlers
void OnWatcher(wxFileSystemWatcherEvent& event);
void OnDirChanged(wxFileDirPickerEvent& event);
// Helper functions
wxString StripPath(const wxString&);
void DeleteFromListbox(const wxString&);
wxFileSystemWatcher m_watcher;
wxListBox* m_listBox;
};
MyFrame::MyFrame()
:wxFrame(NULL, wxID_ANY, "Filesystem watcher frame", wxDefaultPosition,
wxSize(600, 400))
{
// Set up the UI elements.
wxPanel* mainPanel = new wxPanel(this,wxID_ANY);
wxDirPickerCtrl* dirPicker = new wxDirPickerCtrl(mainPanel, wxID_ANY);
m_listBox = new wxListBox(mainPanel, wxID_ANY);
wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL);
sizer->Add(dirPicker, wxSizerFlags(0).Expand().Border(wxALL));
sizer->Add(m_listBox, wxSizerFlags(1).Expand().Border(wxALL&~wxTOP));
mainPanel->SetSizer(sizer);
Layout();
// Set up the event handlers.
m_watcher.SetOwner(this);
dirPicker->Bind(wxEVT_DIRPICKER_CHANGED, &MyFrame::OnDirChanged, this);
Bind(wxEVT_FSWATCHER, &MyFrame::OnWatcher, this);
}
void MyFrame::OnWatcher(wxFileSystemWatcherEvent& event)
{
wxFileName name = event.GetPath();
// Ignore all watch events for folders.
if ( name.IsDir() )
{
return;
}
wxFileName newName = event.GetNewPath();
int changeType = event.GetChangeType();
switch ( changeType )
{
case wxFSW_EVENT_CREATE :
m_listBox->Append( StripPath(name.GetFullPath()) );
break;
case wxFSW_EVENT_DELETE :
DeleteFromListbox( StripPath(name.GetFullPath()) );
break;
case wxFSW_EVENT_RENAME :
DeleteFromListbox( StripPath(name.GetFullPath()) );
m_listBox->Append( StripPath(newName.GetFullPath()) );
break;
case wxFSW_EVENT_MODIFY :
wxFALLTHROUGH;
case wxFSW_EVENT_ACCESS :
wxFALLTHROUGH;
case wxFSW_EVENT_ATTRIB :
wxFALLTHROUGH;
#ifndef __WINDOWS__
case wxFSW_EVENT_UNMOUNT :
wxFALLTHROUGH;
#endif // __WINDOWS__
case wxFSW_EVENT_WARNING :
wxFALLTHROUGH;
case wxFSW_EVENT_ERROR :
wxFALLTHROUGH;
default:
break;
}
}
void MyFrame::OnDirChanged(wxFileDirPickerEvent& event)
{
if ( !::wxDirExists(event.GetPath()) )
{
return;
}
// Remove the current folder from the watch and add the new one.
m_watcher.RemoveAll();
wxString pathWithSep = event.GetPath();
if ( pathWithSep.Right(1) != wxFileName::GetPathSeparator() )
{
pathWithSep << wxFileName::GetPathSeparator();
}
m_watcher.Add(wxFileName(pathWithSep));
// Get a list of the files in new folder.
std::vector<wxString> files;
wxDir dir(pathWithSep);
wxString curName;
if ( dir.GetFirst(&curName, "*", wxDIR_FILES) )
{
files.push_back(StripPath(curName));
}
while ( dir.GetNext(&curName) )
{
files.push_back(StripPath(curName));
}
// Replace the current contents of the listbox with the new filenames.
m_listBox->Clear();
for ( auto it = files.begin() ; it != files.end() ; ++it )
{
m_listBox->Append(*it);
}
}
wxString MyFrame::StripPath(const wxString& name)
{
wxFileName fn(name);
return fn.GetFullName();
}
void MyFrame::DeleteFromListbox(const wxString& name)
{
int index = m_listBox->FindString(name);
if ( index != wxNOT_FOUND )
{
m_listBox->Delete(static_cast<unsigned int>(index));
}
}
class MyApp : public wxApp
{
public:
virtual bool OnInit()
{
MyFrame* frame = new MyFrame();
frame->Show();
return true;
}
};
wxIMPLEMENT_APP(MyApp);
这只是一个简单的例子。还有一些改进的余地:
https://stackoverflow.com/questions/67648890
复制相似问题