我刚刚在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
}
}
}
答案 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 signal和GTK event loop。
如果您想要GObject's signals和poll(2)某些设备,您最好在 GTK事件循环中执行(例如通过调用read(2)或g_source_add_unix_fd等等......)。
你应该花几天时间阅读更多关于Gtk的内容,特别是g_io_channel_unix_new章。
答案 1 :(得分:0)
我有两个解决方案来解决您的问题:
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_add
或g_timeout
触发再次更改状态来避免这种情况。