c - 如何循环更新 GtkProgressBar?

标签 c gtk progress-bar gtk3

我不能在循环中简单地调用gtk_progress_bar_set_fraction,因为在循环结束之前它不会产生任何影响。

如果我使用 gtk_main_iteration(); 强制 main 沿着 gtk_progress_bar_set_fraction 的调用进行迭代,它当然可以工作..但循环处理速度明显较慢。

在循环处理时如何更新进度条?

最佳答案

我使用这个示例来了解进度和线程

#!/usr/bin/python2.7
# -*- coding: utf-8 -*-
'''
Simple example of a PyGTK3 application with a background thread.
'''

import random
import threading
import time

from gi.repository import Gtk, GObject

APP_NAME = 'Threaded GUI Example'
TARGET = 100.0

class WorkerThread(threading.Thread):
    '''
    The worker thread, which would normally do something more useful.

    It is important that the worker thread does not attempt to update the
    GUI. Doing so can cause crashes and weird behaviour.

    @param delegate the object to be informed of progress being made
    '''
    def __init__(self, delegate):
        threading.Thread.__init__(self)
        self.delegate = delegate
        self.counter = 0
        self.done = False

    def run(self):
        '''
        The work done by the thread.

        Overridden from threading.Thread. Sits in a loop until the done
        flag is set, updating a counter and sleeping to simulate some work.
        '''
        while True:
            if self.done:
                print 'Background thread shutting down cleanly'
                break

            # This counter is only updated by one thread, so probably
            # doesn't need a lock, but it needs thinking about.
            self.counter = self.counter + 1 if self.counter < TARGET else 0

            # Ask the main thread to update the GUI when it has time.
            GObject.idle_add(self.delegate.update_progress)

            # Sleep for a little bit ...
            time.sleep(random.uniform(0.01, 0.1))


class Main(Gtk.Window):
    '''
    The main application GUI running in the main thread.
    '''
    def __init__(self):
        Gtk.Window.__init__(self, title=APP_NAME)
        self.set_size_request(500, 300)

        # Lay out the GUI.
        vbox = Gtk.VBox(False, 0)

        # Set up a progress bar to show how the worker is progressing.
        self.progress_bar = Gtk.ProgressBar()
        vbox.pack_start(self.progress_bar, False, False, 0)




        # Set up a text view to show the responsiveness of the GUI.
        scroller = Gtk.ScrolledWindow()
        textview = Gtk.TextView()
        textview.get_buffer().set_text(
            'The counting is going on in the worker thread with the GUI '\
            'handling updates in the idle loop. You can type in the text '\
            'view or resize the window and it should be responsive.\n\n'
        )
        textview.set_wrap_mode(Gtk.WrapMode.WORD)
        scroller.add(textview)
        vbox.pack_start(scroller, True, True, 0)

        self.add(vbox)
        self.show_all()

        # Connect the destroy event so that we can set the done flag and
        # terminate the worker cleanly.
        self.connect("destroy", self.on_quit)

        # Kick off the background thread.
        self.worker = WorkerThread(self)
        self.worker.start()

    def update_progress(self):
        '''
        Update the progress bar.

        The method called on request in the idle loop to update the GUI. The
        worker requests the update using GObject.idle_add()
        @return True to repeat indefinitely, False for a single invocation
        '''
        progress = self.worker.counter / TARGET
        self.progress_bar.set_fraction(progress)
        self.set_title('{} ({}%)'.format(APP_NAME, progress * 100))
        return False

    def on_quit(self, widget):
        '''
        Quit the application

        Handler called when the application is about to quit. Set the done
        flag so that the worker quits cleanly, then quit.
        '''
        self.worker.done = True
        Gtk.main_quit()


if __name__ == '__main__':
    # The background thread will not run concurrently against the main
    # thread without the threads_init() call:
    GObject.threads_init()
    Main()
    Gtk.main()

关于c - 如何循环更新 GtkProgressBar?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29286667/

相关文章:

ios - 将 uint8_t 和 uint16_t 转换为 NSMutableData

c - C 中的 (round)(myFloat) 是什么语法?

c - 对我的一些函数的 undefined reference

.net - GTK+ 和 GTK# 有什么区别,哪个是 "more multiplatform"?

c++ - 我如何获得 giomm-2.4 软件包?

gtk - C - 在 Windows 上安装 GTK 没有麻烦吗?

c# - ProgressBar 从另一个线程更新

javascript - 获取 API 下载进度指示器?

java - 如何在不使用线程的情况下更新 fragment 中的进度条

c - 递归幂函数 : approach