QFileSystemModel——检测空文件夹(使用“AllDirs”过滤器)?

发布于 2024-11-14 12:05:30 字数 3157 浏览 1 评论 0原文

我在 Ruby 中使用 Qt 4.6(通过 QtRuby),并尝试创建一个通用的目录选择对话框,该对话框在查询文件系统和更新目录树(QTreeView)时显示一个小的“正在加载”字形。

更新:我必须说动画没有按预期工作,是否有另一种方法来检测这些事件(正在加载、已加载)?请参阅下面的“另一说明”。

我已经设法通过所使用的 QFileSystemModel 的 rowsInserted 信号连接“新目录加载”事件,工作得很好。我还可以通过 rowsAboutToBeInserted 信号捕获“加载新目录”事件。然而,我尝试播放的动画(一个简单的动画 GIF,用于指示进度,在 QMovie 中加载)正在播放即使已“扩展”的目录为空。这是我正在使用的代码:

# FileSystemModel extension which shows a 'busy' animation
# in a given Qt::Label
class FileSystemModelEx < Qt::FileSystemModel

  # Slot declarations
  slots "handle_ready(QModelIndex, int, int)"
      slots "handle_busy(QModelIndex, int, int)"

  # Parametrised constructor, initializes fields
  def initialize(p_parent, p_label, p_busy_icon, p_ready_icon)

      # Call superclass constructor
      super(p_parent)

      # Set instance vars
      @label = p_label
      @busy_icon = p_busy_icon
      @ready_icon = p_ready_icon

      # Connect 'finished loaded' event
      Qt::Object.connect(self,
                        SIGNAL('rowsAboutToBeInserted(QModelIndex, int, int)'),
                        self,
                        SLOT('handle_busy(QModelIndex, int, int)'))

      # Connect 'loading' event
      Qt::Object.connect(self, 
                        SIGNAL('rowsInserted(QModelIndex, int, int)'),
                        self,
                        SLOT('handle_ready(QModelIndex, int, int)'))
  end

  # Loading finished event, changes icon state to ready
  def handle_ready(p_index, p_start, p_end)
      set_icon(false)   

      puts "    done - loaded #{rowCount(p_index)} folders"
  end

  # Loading started event, changes icon state to busy
  def handle_busy(p_index, p_start, p_end)
      set_icon(true)

      path = fileInfo(p_index).canonicalFilePath
    puts "Loading . . . path = '#{path}'"
  end

  # Overriden start loading event
  def fetchMore(p_index)
      handle_busy(p_index, nil, nil)
      super(p_index)
  end

  # Utility method, switches icons, depending on a given state
  def set_icon(p_busy) 
      movie = (p_busy ? @busy_icon : @ready_icon)
      @label.setMovie(movie)
      movie.start
  end   

end # class FileSystemModelEx

我的问题是:如果加载的文件夹为空,如何阻止动画播放?无法预先过滤空目录,不是吗?

另一方面,除了上述方法之外,还有其他方法可以实现此类“正在加载”/“已加载”事件处理程序吗?我查看了信号、虚拟信号(fetchMorecanFetchMore,无济于事),扫描了源但我无法到达发送线程检索任务的调用更多文件。覆盖 eventtimerEvent 没有帮助。

为了完成起见,这里也是我正在使用的 QFileSystemModel:

# Creates a FileSystemModel which display folders only
def create_model
    @model = FileSystemModelEx.new(self, 
                @form.iconPlaceholderDir, 
                @loading_icon, @folder_icon)

    @model.setReadOnly(true)
    @model.setFilter(Qt::Dir::NoDotAndDotDot | Qt::Dir::AllDirs)
    @model.setRootPath(Qt::Dir.rootPath)


    @form.shellTreeView.setModel(@model)
end

任何帮助将不胜感激,提前致谢! 如果需要的话我可以提供更多细节,没问题。

I'm using Qt 4.6 within Ruby (via QtRuby) and am trying to make a generic Directory Selection Dialog which displays a small "loading" glyph whilst the file system is being queried and the Directory Tree (QTreeView) is being updated.

UPDATE: I must say that the animation doesn't work as expected, is there another way of detecting these events (loading, loaded) ? See "On another note" below.

I have managed to connect the "new directories loaded" event via the rowsInserted Signal of the used QFileSystemModel, works quite fine. I'm also able to catch the "loading new directories" event via the rowsAboutToBeInserted signal. Yet the animation I'm trying to play (a simple animated GIF to indicate progress, loaded within a QMovie) is getting played even if the directory which has been 'expanded' is empty. Here is the code I am using :

# FileSystemModel extension which shows a 'busy' animation
# in a given Qt::Label
class FileSystemModelEx < Qt::FileSystemModel

  # Slot declarations
  slots "handle_ready(QModelIndex, int, int)"
      slots "handle_busy(QModelIndex, int, int)"

  # Parametrised constructor, initializes fields
  def initialize(p_parent, p_label, p_busy_icon, p_ready_icon)

      # Call superclass constructor
      super(p_parent)

      # Set instance vars
      @label = p_label
      @busy_icon = p_busy_icon
      @ready_icon = p_ready_icon

      # Connect 'finished loaded' event
      Qt::Object.connect(self,
                        SIGNAL('rowsAboutToBeInserted(QModelIndex, int, int)'),
                        self,
                        SLOT('handle_busy(QModelIndex, int, int)'))

      # Connect 'loading' event
      Qt::Object.connect(self, 
                        SIGNAL('rowsInserted(QModelIndex, int, int)'),
                        self,
                        SLOT('handle_ready(QModelIndex, int, int)'))
  end

  # Loading finished event, changes icon state to ready
  def handle_ready(p_index, p_start, p_end)
      set_icon(false)   

      puts "    done - loaded #{rowCount(p_index)} folders"
  end

  # Loading started event, changes icon state to busy
  def handle_busy(p_index, p_start, p_end)
      set_icon(true)

      path = fileInfo(p_index).canonicalFilePath
    puts "Loading . . . path = '#{path}'"
  end

  # Overriden start loading event
  def fetchMore(p_index)
      handle_busy(p_index, nil, nil)
      super(p_index)
  end

  # Utility method, switches icons, depending on a given state
  def set_icon(p_busy) 
      movie = (p_busy ? @busy_icon : @ready_icon)
      @label.setMovie(movie)
      movie.start
  end   

end # class FileSystemModelEx

My question would be: How can I keep the animation from playing, if the loaded folder is empty? One cannot filter the empty directories beforehand, isn't that so?

On another note, is there another way of implementing such 'loading' / 'loaded' event handlers, other than that described above? I've looked around the signals, virtuals (fetchMore and canFetchMore, to no avail), scanned the source yet I cannot reach the call which sends the thread on its quest of retrieving more files. Overriding event or timerEvent doesn't help.

For completion's sake, here is the QFileSystemModel I'm using as well:

# Creates a FileSystemModel which display folders only
def create_model
    @model = FileSystemModelEx.new(self, 
                @form.iconPlaceholderDir, 
                @loading_icon, @folder_icon)

    @model.setReadOnly(true)
    @model.setFilter(Qt::Dir::NoDotAndDotDot | Qt::Dir::AllDirs)
    @model.setRootPath(Qt::Dir.rootPath)


    @form.shellTreeView.setModel(@model)
end

Any help would be appreciated, thanks in advance!
I can provide further details if the need arises, no problem.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

伏妖词 2024-11-21 12:05:30

您应该尝试连接模型的 directoryLoaded(const QString&) 插槽。当目录已完全处理时它会发出信号。

使用 qt4-ruby (2.1.0) 构建的示例应用程序,针对 Ruby 1.8.7 和 Qt 4.7.3

#!/usr/bin/ruby -w
require 'Qt4'

class MyObject < Qt::Object
    slots "mySlot(QString)"
    def mySlot(path)
        print "Done loading ", path, "\n"
    end
end

a = Qt::Application.new(ARGV)
m = Qt::FileSystemModel.new
v = Qt::TreeView.new
m.setRootPath("/")
v.setModel(m)
o = MyObject::new
Qt::Object.connect(m, SIGNAL('directoryLoaded(QString)'), o, SLOT('mySlot(QString)'))
v.show
a.exec

(请友善,这是我的第一个 ruby​​“程序”...)

You should try hooking up the model's directoryLoaded(const QString&) slot. It signals when the directory has been fully processed.

Sample app with qt4-ruby (2.1.0) build againts Ruby 1.8.7 and Qt 4.7.3

#!/usr/bin/ruby -w
require 'Qt4'

class MyObject < Qt::Object
    slots "mySlot(QString)"
    def mySlot(path)
        print "Done loading ", path, "\n"
    end
end

a = Qt::Application.new(ARGV)
m = Qt::FileSystemModel.new
v = Qt::TreeView.new
m.setRootPath("/")
v.setModel(m)
o = MyObject::new
Qt::Object.connect(m, SIGNAL('directoryLoaded(QString)'), o, SLOT('mySlot(QString)'))
v.show
a.exec

(Be kind, this is my very first ruby "program"...)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文