我有一个应用程序,我试图修改它,以便工作线程可以告诉窗口使用新数据更新自身。
变量定义如下:
Display *d;
Window w;
XEvent exppp;
Run Code Online (Sandbox Code Playgroud)
该窗口使用以下代码启动:
XEvent e;
d = XOpenDisplay(NULL);
if (d == NULL) 
  return 0;
s = DefaultScreen(d);
w = XCreateSimpleWindow(d, RootWindow(d, s), 10, 10, 200, 800, 1,
                        BlackPixel(d, s), WhitePixel(d, s));
XSelectInput(d, w, ExposureMask | KeyPressMask);
XMapWindow(d, w);
while (1) {
  XNextEvent(d, &e);
  if (e.type == Expose || e.type == KeyPress) {
    // redraw routine goes here
  }
}
Run Code Online (Sandbox Code Playgroud)
我试图用来让窗口重绘的是一个可以被另一个线程调用的函数:
void graphical_out::redraw()
{
  exppp.type = Expose;
  XSendEvent(d, w, false, Expose, &exppp);
}
Run Code Online (Sandbox Code Playgroud)
并且窗口仅在重新调整大小或接收按键时更新自身。这似乎有点像一个新手问题,但谷歌在这个问题上让我失望。对我做错了什么有什么建议吗?
XSendEvent是错误的。您需要传递掩码 ( ExposureMask),而不是事件类型。exppp.xexpose.window = w;是强制性的(的窗口参数XSendEvent是不所述的窗口XEvent结构)。memset(&exppp, 0, sizeof(exppp));,以防万一。更新在多线程程序中,需要在XFlush这里和那里调用(尽管永远不能保证多线程与 Xlib 一起使用)。
这段代码对我有用:
#include <X11/Xlib.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <memory.h>
Display *d;
Window w;
int s;
void* tp (void* q)
{
    XEvent exppp;
    while (1)
    {
        sleep (3);
        printf ("Sending event of type Expose\n");
        memset(&exppp, 0, sizeof(exppp));
        exppp.type = Expose;
        exppp.xexpose.window = w;
        XSendEvent(d,w,False,ExposureMask,&exppp);
        XFlush(d);
    }
    return NULL;
}
int main ()
{
    XEvent e;
    pthread_t thread;
    d = XOpenDisplay(NULL);
    if (d == NULL)
        return 0;
    s = DefaultScreen(d);
    w = XCreateSimpleWindow(d, RootWindow(d, s), 10, 10, 200, 800, 1,
                            BlackPixel(d, s), WhitePixel(d, s));
    XSelectInput(d, w, ExposureMask | KeyPressMask);
    XMapWindow(d, w);
    pthread_create(&thread, NULL, tp, NULL);
    while (1) {
        XNextEvent(d, &e);
        if (e.type == Expose) {
            printf ("Got Expose event%s\n", e.xexpose.send_event ? " (SendEvent)" : "");
        }
        else if (e.type == KeyPress) {
            printf ("Got KeyPress event%s\n", e.xkey.send_event ? " (SendEvent)" : "");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)
它可能对你有用,或者它可能会爆炸。Xlib 不是线程安全的,使用风险自负。