繁体   English   中英

如何使 Motif Push Button 小部件显示为永久按下?

[英]How can I make Motif Push Button widget to appear as permanently pushed?

我已经为 select FreeBSD 中的音频通道编写了一个简单的工具。

这是代码:

xaudio.c

#include <Xm/Xm.h>
#include <Xm/PushB.h>
#include <Xm/MainW.h>
#include <Xm/RowColumn.h>

#include <stdio.h>
#include <stdlib.h>

#include "devices.h"

struct button_data {
   int device_num;
   Widget button;
};

/* GLOBAL VARIABLES */
int num_devices;
struct device *devices;
struct button_data *buttons;

void button_callback(Widget widget, XtPointer client_data, XtPointer call_data);
void create_device_buttons(Widget parent, struct device *devices, int num_devices);

void button_callback(Widget widget, XtPointer client_data, XtPointer call_data) {
   int i;
   struct button_data *data = (struct button_data *)client_data;
   int device_num = data->device_num;

   // unclick all other buttons
   for (i = 0; i < num_devices; i++) {
      if (buttons[i].button != widget) {
         XtVaSetValues(buttons[i].button, XmNset, False, NULL);
      }
   }

   // click this button
   XtVaSetValues(widget, XmNset, True, NULL);
   
   // set audio device
   set_audio_device(device_num);
}

void create_device_buttons(Widget parent, struct device *devices, int num_devices) {
   int i;
   XmString label;
   struct button_data *data;
   Arg args[5];
   int n;

   buttons = malloc(num_devices * sizeof(struct button_data));
   if (buttons == NULL) {
      perror("Failed to allocate memory");
      exit(EXIT_FAILURE);
   }

   for (i = 0; i < num_devices; i++) {
      // create button
      n = 0;
      label = XmStringCreateLocalized(devices[i].description);
      XtSetArg(args[n], XmNlabelString, label); n++;
      buttons[i].button = XmCreatePushButton(parent, "device_button", args, n);
      XmStringFree(label);
      XtManageChild(buttons[i].button);

      // set button data
      buttons[i].device_num = devices[i].number;

      // set button callback
      XtAddCallback(buttons[i].button, XmNactivateCallback, button_callback, &buttons[i]);
   }
}

int main(int argc, char *argv[]) {
   XtAppContext app;
   Widget top_level, main_window, button_rowcolumn;
   int default_device;

   int n=0;
   Arg args[10];

   top_level = XtVaOpenApplication(&app, "XAudio", NULL, 0, &argc, argv, NULL, sessionShellWidgetClass, NULL);
   main_window = XmCreateMainWindow(top_level, "main_window", NULL, 0);
   XtManageChild(main_window);
   n=0;
   XtSetArg(args[n], XmNorientation, XmVERTICAL); n++;
   button_rowcolumn = XmCreateRowColumn(main_window, "button_rowcolumn", args, n);    
   XtManageChild(button_rowcolumn);

   /* GET LIST OF DEVICES AND DEFAULT DEVICE */
   default_device = get_default_device(&devices, &num_devices);

   int i=0;
   for(i=0; i<num_devices; i++) {
        printf("%d %s\n", devices[i].number, devices[i].description);
  }

   create_device_buttons(button_rowcolumn, devices, num_devices);
   
   XtRealizeWidget(top_level);
   
   /* CLICK DEFAULT BUTTON */
   if (default_device >= 0) {
      XtVaSetValues(buttons[default_device].button, XmNset, True, NULL);
   }

   XtAppMainLoop(app);
   
   free(devices);
   free(buttons);
   
   return 0;
}

设备.c:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct device {
   int number;
   char description[256];
};

void set_audio_device(int device_num) {
   char command[256];
   sprintf(command, "sysctl hw.snd.default_unit=%d", device_num);
   system(command);
}

int get_default_device(struct device **devices, int *num_devices) {
   FILE *fp;
   char *line = NULL;
   size_t len = 0;
   ssize_t read;
   int num_dev = 0;
   int default_device = -1;

   fp = popen("cat /dev/sndstat", "r");
   if (fp == NULL) {
      perror("Failed to run command");
      exit(EXIT_FAILURE);
   }

   while ((read = getline(&line, &len, fp)) != -1) {
      if (strstr(line, "pcm") == line) {
         // line starts with "pcm", so it is a device line
         // increase number of devices and reallocate memory
         num_dev++;
         *devices = realloc(*devices, num_dev * sizeof(struct device));
         if (*devices == NULL) {
            perror("Failed to allocate memory");
            exit(EXIT_FAILURE);
         }

         // get device number
         sscanf(line, "pcm%d:", &(*devices)[num_dev - 1].number);

         // get description
         char *start = strchr(line, '<');
         char *end = strchr(line, '>');
         if (start != NULL && end != NULL) {
            int length = end - start - 1;
            strncpy((*devices)[num_dev - 1].description, start + 1, length);
            (*devices)[num_dev - 1].description[length] = '\0';
         }

         // check if this is the default device
         if (strstr(line, "default") != NULL) {
            default_device = num_dev - 1;
         }
      }
   }

   *num_devices = num_dev;
   pclose(fp);
   return default_device;
}

设备.h:

#ifndef DEVICES_H
#define DEVICES_H

#include <stdio.h>
#include <stdlib.h>

struct device {
   int number;
   char description[256];
};

void set_audio_device(int device_num);
int get_default_device(struct device **devices, int *num_devices);

#endif

以及相应的 makefile(对于 FreeBSD):

CC = cc
CFLAGS = -Wall -Wextra -I/usr/local/include
LDFLAGS = -Wall -Wextra -L/usr/local/lib -lXm -lXt -lX11 

all: xaudio

xaudio: xaudio.o devices.o
        $(CC) $(LDFLAGS) -o $@ xaudio.o devices.o

xaudio.o: xaudio.c devices.h
        $(CC) $(CFLAGS) -c -o $@ $<

devices.o: devices.c devices.h
        $(CC) $(CFLAGS) -c -o $@ $<

clean:
        rm -f *.o xaudio

该程序编译并运行(它按预期切换音频通道)。 However, my intended behaviour was that the channel selected appeared as a permanently pushed button, and that when a new channel was selected the pushed button changed accordingly. 排序一种“可选按钮集”。

据我了解,这种行为是通过以下小部件参数实现的:

XtVaSetValues(buttons[default_device].button, XmNset, True, NULL);

然而,正如此处所见,这并没有发生,按钮似乎总是未被点击,除了按下时的正常动态点击效果。

在此处输入图像描述

您描述的所需行为是“单选按钮”的用途。 在 Motif 中,我相信您需要 XmCreateRadioBox function。

不,不能将 XmPushButton 配置为看起来总是被按下。 尝试使用 XmToggleButton 而不是 XmPushButton。 将 XmNindicatorOn 设置为 False 以去除菱形复选框。 然后 XmNset,False 会让它看起来很压抑。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM