gtk_main()和while(1)Raspberry Pi 3

时间:2017-02-21 14:49:28

标签: c raspberry-pi gtk geany

我刚刚在Rasberry pi 3上用C语言开始了我的第一个项目,我想创建我的第一个触摸面板GUI应用程序。 我的目标是运行while(1)循环来控制覆盆子I / O和gtk_main函数来打开一个简单的窗口。

调用gtk_main()之后,其余的代码都无法正常工作。我知道它是由gtk_main创建它自己的循环引起的。有没有办法同时运行这两个循环?

#include <stdio.h>    // Used for printf() statements
#include <wiringPi.h> // Include WiringPi library!
#include <gtk/gtk.h>

// Pin number declarations. We're using the Broadcom chip pin numbers.
const int pwmPin = 18; // PWM LED - Broadcom pin 18, P1 pin 12
const int ledPin = 23; // Regular LED - Broadcom pin 23, P1 pin 16
const int butPin = 21; // Active-low button - Broadcom pin 17, P1 pin 11    

const int pwmValue = 0; // Use this to set an LED brightness

int main(int argc, char *argv[]){

    int add = 0;
    int sign = 1;
    // Setup stuff:
    wiringPiSetupGpio(); // Initialize wiringPi -- using Broadcom pin numbers

    pinMode(pwmPin, PWM_OUTPUT); // Set PWM LED as PWM output
    pinMode(ledPin, OUTPUT);     // Set regular LED as output
    pinMode(butPin, INPUT);      // Set button as INPUT
    pullUpDnControl(butPin, PUD_UP); // Enable pull-up resistor on button

    GtkWidget *window;

    gtk_init (&argc, &argv);

    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
    gtk_widget_show (window);

    gtk_main ();

    // Loop (while(1)):
    while(1)
    {
        if (digitalRead(butPin)) // Button is released if this returns 1
        {
            pwmWrite(pwmPin, pwmValue+add); // PWM LED at bright setting
            digitalWrite(ledPin, LOW);     // Regular LED off
            add=add+(sign*50);
            if (add==1000) sign=-1;
            if (add==0) sign=1;
            delay(50);
        }
        else // If digitalRead returns 0, button is pressed
        {
            pwmWrite(pwmPin, 1024 - pwmValue); // PWM LED at dim setting
            // Do some blinking on the ledPin:
            digitalWrite(ledPin, HIGH); // Turn LED ON
            delay(75); // Wait 75ms
            digitalWrite(ledPin, LOW); // Turn LED OFF
            delay(75); // Wait 75ms again
        }
    }    

}

3 个答案:

答案 0 :(得分:1)

gtk_main documented为:

  

运行主循环,直到调用gtk_main_quit()

     

您可以将来电嵌套到gtk_main()。在这种情况下,gtk_main_quit()将使主循环的最内部调用返回。

所以你需要明确地{/ 3>} 调用gtk_main_quit(我想你不会)。

所以行为是预料之中的。您可能希望处理window上的callback(通过您的 GTK信号处理程序为该事件明确调用 gtk_main_quit) 。您需要阅读更多内容,尤其是"delete-event" GTK signalGTK event loop

如果您想要GObject's signalspoll(2)某些设备,您最好在 GTK事件循环中执行(例如通过调用read(2)g_source_add_unix_fd等等......)。

你应该花几天时间阅读更多关于Gtk的内容,特别是g_io_channel_unix_new章。

答案 1 :(得分:0)

我有两个解决方案来解决您的问题:

  • 你可create a timer调用函数来处理每{100}的butPin值,
  • 您可以使用线程:

    void *start_gtk_thread(void *arg)
    {
        gtk_main();
        return NULL;
    }
    void *start_pin_thread(void *arg)
    {
        while(1)
        {
            if (digitalRead(butPin)) // Button is released if this returns 1
            {
                 ....
            }
            return NULL;
        }
    }
    

    在您的主要功能中

    gtk_widget_show (window);
    
    /* threads id*/
    pthread_t tid[2];
    
    /* create threads */        
    pthread_create(&tid[0], NULL, start_gtk_thread, NULL);
    pthread_create(&tid[1], NULL, start_pin_thread, NULL);
    
    /* wait for threads (warning, they should never terminate) */ 
    pthread_join(id[0], NULL);
    pthread_join(id[1], NULL);
    

答案 2 :(得分:0)

移除你的while循环并使用g_idle_add和/或g_timeout来触发你的回调。这定义了何时调用您的代码。然后在你的回调中,做你的引脚I / O控制的东西。请记住,使用delay或类似于sleep的任何阻止功能会冻结您的用户界面相同的时间。您可以使用g_idle_addg_timeout触发再次更改状态来避免这种情况。