如何解决尝试将文本附加到 Xm 文本小部件时出现多线程或 Motif 小部件问题
我正在尝试使用 TextWidget 作为日志,其中以编程方式添加文本。
通过使用 XmTextInsert
、XtVaSetValues
和 XmTextShowPosition
,我可以将文本附加到文本小部件,但是我注意到只有当小部件具有焦点或滚动鼠标时才会更新文本指向文本小部件区域的指针。否则,Widget 似乎只更新了大约 5/6 秒,因此您会看到一次出现多行。
我无法确定这是与 Motif 相关的问题还是纯粹的 X11/Xt/Xm 多线程问题,但很明显附加的代码缺少相关内容。
例如,此源代码只有 TextWidget,并且更新工作正常,即使焦点在另一个应用程序中,每秒钟您都会看到一个新的 TEST 字添加到 Text Widget:
#include <Xm/Xm.h>
#include <Xm/Form.h>
#include <Xm/Text.h>
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
void displayMessage(char *textLineBuffer);
void createWindow(int argc,char *argv[]);
void *logText(void *arg);
/* X11 RELATED VARIABLES */
XtAppContext context;
Widget toplevel;
Widget busForm;
Widget textWidget;
pthread_mutex_t textWidgetMutex;
long textWidgetLength = 0;
int main(int argc,char *argv[]) {
pthread_t thread;
/* INITIALIZE MULTITHREAD X11 ENVIRONMENT */
XInitThreads();
/* CREATE X WINDOW */
createWindow(argc,argv);
/* GET NEW THREAD TO PROCESS QUEUES */
/* PARENTS HANDLES X11 */
pthread_create(&thread,NULL,logText,NULL);
/* BEGIN X11 APPLICATION */
XtAppMainLoop(context);
}
void *logText(void *arg) {
/* READ CLIENT QUEUE MESSAGES */
while(1) {
sleep(1);
displayMessage("TEST\n");
}
}
void createWindow(int argc,char *argv[]){
Arg al[10];
int ac;
xmstringCharSet char_set = xmsTRING_DEFAULT_CHARSET;
char pidString[50];
/* CREATE TOP LEVEL */
sprintf(pidString,"Bus Client %d",getpid());
toplevel = XtAppInitialize(&context,pidString,&argc,argv,0);
/* RESIZE TOP LEVEL */
ac = 0;
XtSetArg(al[ac],XmNwidth,300); ac++;
XtSetArg(al[ac],XmNheight,300); ac++;
XtSetValues(toplevel,al,ac);
/* CREATE TOP LEVEL FORM MANAGER */
ac = 0;
busForm = XmCreateForm(toplevel,"busForm",ac);
XtManageChild(busForm);
/* CREATE TEXT WIDGET */
ac = 0;
XtSetArg(al[ac],XmNtopAttachment,XmATTACH_FORM); ac++;
XtSetArg(al[ac],XmNleftAttachment,XmNrightAttachment,XmNbottomAttachment,XmNeditMode,XmMULTI_LINE_EDIT); ac++;
XtSetArg(al[ac],XmNscrollingPolicy,XmVARIABLE); ac++;
XtSetArg(al[ac],XmNscrollBardisplayPolicy,xmsTATIC); ac++;
XtSetArg(al[ac],XmNscrollHorizontal,FALSE); ac++;
XtSetArg(al[ac],XmNeditable,FALSE); ac++;
textWidget = XmCreateScrolledText(busForm,"textWidget",ac);
XtManageChild(textWidget);
/* disPLAY TOP LEVEL */
XtRealizeWidget(toplevel);
}
void displayMessage(char *textLineBuffer) {
pthread_mutex_lock(&textWidgetMutex);
XmTextInsert(textWidget,textWidgetLength,textLineBuffer);
textWidgetLength += strlen(textLineBuffer);
XtVaSetValues(textWidget,XmNcursorPosition,NULL);
XmTextShowPosition(textWidget,textWidgetLength);
pthread_mutex_unlock(&textWidgetMutex);
}
但是,如果添加按钮,当 Motif 应用程序中的焦点在 Button Widget 中时,文本不会更新,直到鼠标滚过 Text Widget。如果您单击“文本小部件”,则文本会像前面的示例一样在那里不断更新。
这是源代码和相应的例子。
#include <Xm/Xm.h>
#include <Xm/Form.h>
#include <Xm/Text.h>
#include <Xm/PushB.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <pthread.h>
#include <unistd.h>
void displayMessage(char *textLineBuffer);
void createWindow(int argc,char *argv[]);
void sendButtonCB(Widget w,XtPointer client_data,XtPointer call_data);
void *logText(void *arg);
/* X11 RELATED VARIABLES */
XtAppContext context;
Widget toplevel;
Widget busForm;
Widget textWidget;
Widget registerButton;
Widget sendButton;
pthread_mutex_t textWidgetMutex;
long textWidgetLength = 0;
/* BUS CLIENT SYS V QUEUE VARIABLES */
int client_queue_id;
key_t client_queue_key;
int client_message_id;
int main(int argc,ac);
XtManageChild(busForm);
/* CREATE SEND BUTTON WIDGET */
ac = 0;
XtSetArg(al[ac],XmATTACH_NONE); ac++;
XtSetArg(al[ac],XmNlabelString,xmstringCreateLtoR("Send",char_set)); ac++;
sendButton = XmCreatePushButton(busForm,"sendButton",ac);
XtManageChild(sendButton);
XtAddCallback(sendButton,XmNactivateCallback,sendButtonCB,NULL);
/* CREATE TEXT WIDGET */
ac = 0;
XtSetArg(al[ac],XmATTACH_WIDGET); ac++;
XtSetArg(al[ac],XmNtopWidget,registerButton); ac++;
XtSetArg(al[ac],textWidgetLength);
pthread_mutex_unlock(&textWidgetMutex);
}
解决方法
我刚刚发现:
void displayMessage(char *textLineBuffer) {
pthread_mutex_lock(&textWidgetMutex);
XmTextInsert(textWidget,textWidgetLength,textLineBuffer);
textWidgetLength += strlen(textLineBuffer);
XmUpdateDisplay(textWidget);
pthread_mutex_unlock(&textWidgetMutex);
}
强制小部件重绘。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。