【问题标题】:Having time waiting in C++ programs在 C++ 程序中有时间等待
【发布时间】:2015-01-22 12:33:11
【问题描述】:

我读过this 的书。对于图形,我在编译器 MS Visual Studio 2012 上安装了 FLTK。我使用的机器是 MS Windows 7。
这本书我一直读到第 17 章,我还没有研究过任何等待的方法。等待是指执行一条语句,让系统等待一段时间,然后执行第二条语句。

下面是一个在窗口上绘制两个形状的简单示例。本书使用的图形库是here

例如,在这段代码中,我有两个 circles,它们有两个不同的位置和不同的半径。
我想先附加circle (c1),而不是等待一秒钟,分离c1,这次附加c2。请问什么是等待一秒钟(或更多)的最简单方法?

#include <Windows.h>
#include <GUI.h>
using namespace Graph_lib;

//---------------------------------

class Test : public Window {

public:
    Test(Point p, int w, int h, const string& title):
        Window(p, w, h, title),
        quit_button(Point(x_max()-90,20), 60, 20, "Quit", cb_quit),
        c1(Point(100,100), 50),
        c2(Point(300,200), 100) {
            attach(quit_button);
            attach(c1);
            attach(c2);
    }

private:
    Circle c1, c2;

    Button quit_button;

    void quit() { hide(); }
    static void cb_quit(Address, Address pw) {reference_to<Test>(pw).quit();}
};

//------------------

int main()  {
        Test ts(Point(300,250), 800, 600, "Test"); 
        return gui_main();
}

【问题讨论】:

    标签: c++ visual-c++ visual-studio-2012 fltk


    【解决方案1】:

    如果你使用的是 c++11:

    std::this_thread::sleep_for(std::chrono::seconds(1));
    

    否则使用 Windows 功能睡眠。

    如果你想等待而不阻塞主线程,你可以使用 std::async:

    #include <future>
    
    // in your Test's constructor
    std::async([&]()
    {
        attach(quit_button);
        attach(c1);
        std::this_thread::sleep_for(std::chrono::seconds(1));
        attach(c2);
    });
    

    这可能不起作用,因为我对您正在使用的库了解不多。

    【讨论】:

    • 我在attach(c1)attach(c2) 之间添加了该代码,并且还包括了 标头。但我有 4 个错误。其中之一 Error 8 error C3083: 'this_thread': the symbol to the left of a '::' must be a type c:\users\cs\documents\visual studio 2012\projects\test_4\test_4\test_4 .cpp 18.
    • 谢谢。我添加了它,代码可以运行。但这不是我想要的。此方法的作用类似于 Sleep(1000)。请阅读以下答案的cmets。
    【解决方案2】:

    您需要使用callbacks 来延迟绘图。 FLTK 中的add_timeout 方法允许您设置一个计时器,该计时器将在延迟后调用一次。在回调中你可以附加c2

    attach(c1)attach(c2) 之间休眠不会将控制权传递回GUI 线程以允许其绘制任何内容。通过使用add_timeout,控件被传回GUI线程,因此它可以绘制c1。一秒钟后,您的回调将被调用,您可以在其中附加c2

    // The function that will be called after the timeout.  The testWindow object will be of type Test*
    void callback(void* testWindow)
    {
        Test* t = reinterpret_cast<Test*>(testWindow);
        t->doCallback();
    }
    
    class Test : public Window 
    {
    public:
        Test(Point p, int w, int h, const string& title):
            Window(p, w, h, title),
            quit_button(Point(x_max()-90,20), 60, 20, "Quit", cb_quit),
            c1(Point(100,100), 50),
            c2(Point(300,200), 100)
        {
            attach(quit_button);
            attach(c1);
            // Setup the timeout and pass a pointer to the Test window to the call back
            Fl::add_timeout(1.0, callback, this);
        }
    
        // Method that is called by callback() and will attach c2
        void doCallback()
        {
            attach(c2);
        }
    
        // rest of class
    

    【讨论】:

    • 感谢您的回答。但它们对我来说都是新的。而且我是新手。你能写一个简单的代码让系统等待一秒钟吗?
    • @s.r.a 我添加了一个代码示例,但我没有 FLTK,因此它可能无法立即工作。
    • 我已经安装了 FLTK,它对我来说很好用。非常感谢你。我测试代码并知道结果。
    • 我将FI::(大写i)更改为Fl::(小l)。并将void callback(void* testWindow) 正文放在班级下方,但再次出现4个错误。其中之一是:_Error 8 错误 C3867:'Fl_Widget::callback':函数调用缺少参数列表;使用 '&Fl_Widget::callback' 创建指向成员 c:\users\cs\documents\visual studio 2012\projects\test_4\test_4\test_4.cpp 22 _ 的指针
    • 回调需要在上面声明它被使用的地方(但如果需要,可以在下面定义)。我已经修复了示例中的大小写错误。
    【解决方案3】:

    你想使用睡眠功能,需要几毫秒:

    Sleep(1000);
    

    【讨论】:

    • 感谢您的回答。但是 Sleep(1000) 不允许系统显示c1 圆圈。我想看到第一个圆圈,然后一秒钟后看到另一个。
    • @s.r.a 所以显示c1 圆圈,然后 Sleep(1000),然后显示下一个圆圈。
    • Sleep() 将窗口带到逗号,并且不让 c1 或任何先前的形状可见。
    【解决方案4】:

    正如您所发现的,Sleep 不是答案,因为您需要在等待时让控制权传回系统,否则窗口将不会更新。

    您需要的是超时。 FLTK提供add_timeout

    http://www.fltk.org/doc-1.1/Fl.html#Fl.add_timeout

    【讨论】:

    • 感谢您的回复。
    猜你喜欢
    • 1970-01-01
    • 2020-07-16
    • 1970-01-01
    • 1970-01-01
    • 2021-12-15
    • 1970-01-01
    • 2010-11-22
    • 2022-07-23
    • 2014-03-21
    相关资源
    最近更新 更多