【问题标题】:Color pairs in ncurses not working properly in classesncurses 中的颜色对在课堂上无法正常工作
【发布时间】:2016-09-23 02:49:48
【问题描述】:

我正在使用 ncurses 制作一个基本的终端应用程序引擎。我制作了一个基本的窗口类,它存储您正在使用的窗口,并允许您在上面写字。现在,我正在做一个 ColorWindow 类,它继承自 BasicWindow,并且应该允许您使用颜色进行编写。根据抽象,我在类的一种方法中初始化我需要的颜色对,这里是示例代码:

编辑:我在这里写所有代码

#include <ncurses.h>
#include <unistd.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <iomanip>
#include <locale>
#include <sstream>
#include <string>

class ColorWindow : public BasicWindow {
private:
    int npairs;
    bool canColor;
    void initializePairs() {
        init_pair(1, COLOR_RED, COLOR_BLACK);
        init_pair(2, COLOR_GREEN, COLOR_BLACK);
        init_pair(3, COLOR_YELLOW, COLOR_BLACK);
        init_pair(4, COLOR_BLUE, COLOR_BLACK);
        init_pair(5, COLOR_MAGENTA, COLOR_BLACK);
        init_pair(6, COLOR_CYAN, COLOR_BLACK);
        init_pair(7, COLOR_WHITE, COLOR_BLACK);

        npairs = 8;
     }

   public:
    ColorWindow() {
        if(has_colors()) {
           initializePairs();
           this->canColor = true;
        }
        else {
           this->canColor = false;
        }
    }

    ColorWindow(int he, int wi, int stx, int sty) : BasicWindow(he, wi, stx, sty) {
         if(has_colors()) {
             initializePairs();
             this->canColor = true;
         }
         else {
             this->canColor = false;
         }
     }

    int addColorPair(int foreground, int background) {
         if(foreground < 0 || foreground > 7 
              || background < 0 || background > 7)
              return -1;

         init_pair(npairs, foreground, background);
         npairs++;

         return npairs-1;
    }

    bool ColorWindow::writeStringWithColor(int x, int y,const char* message, int pair) {
        if(!isInLimits(x, y))
           return false;

        if(pair >= npairs) 
          return false;

        if(canColor)
          return false;

        wattron(getContainer(), COLOR_PAIR(pair));
        mvwprintw(getContainer(), x, y, message);
        wattroff(getContainer(), COLOR_PAIR(7));
     }

    bool changeColor(int color, int r, int g, int b) {
         if(!can_change_color())
             return false;

         if(color < 0 || color > 7 || r < 0 || r > 1000 
             || g < 0 || g > 1000 || b < 0 || b > 1000)
             return false;

         init_color(color, r, g, b);

         return true;
    }

};

class BasicWindow {
   private:
    WINDOW* container;
    int startx, starty, height, width;

   public:
    BasicWindow() {
      this->height = 20;
      this->width = 84;
      this->starty = (LINES - height) / 2;  /* Calculating for a center placement */
      this->startx = (COLS - width) / 2;
    }

    BasicWindow(int he, int wi, int stx, int sty) {
      this->height = he;
      this->width = wi;
      this->starty = sty;
      this->startx = stx;
    }
    

    WINDOW* createNewContainer() {
          this->container = newwin(height, width, starty, startx);

          wrefresh(this->container);        /* Show that box        */

          return getContainer();
    }

    WINDOW* getContainer() {
          return this->container;
    }

    bool writeString(int x, int y, const char* message) {
        if(!isInLimits(x, y))
            return false;

            mvwprintw(this->container, x, y, message);
        }


    void refreshContainer() {
        refresh();
        wrefresh(this->container);      /* Show that box        */
    }

    void destroyWindow() {
         wborder(this->container, ' ', ' ', ' ',' ',' ',' ',' ',' ');
        
         wrefresh(this->container);
         delwin(this->container);
   }

    bool isInLimits(int x, int y) {
         if(x < 0 || x >= this->width-1) {
             return false;
         }
         if(y < 0 || y >= this->height-1) {
              return false;
         }
         return true;
};

这里是主要的:

 #include <iostream>
 #include <unistd.h>
 #include <ncurses.h>
 #include "windows.h"

 int main() {
    ColorWindow cw = ColorWindow(20, 80, 0, 0);


    initscr();          /* Start curses mode        */
    cbreak();           /* Line buffering disabled, Pass on
                        * everty thing to me        */
    keypad(stdscr, TRUE);
    start_color();

    WINDOW* container;

    container = cw.createNewContainer();
    cw.writeStringWithColor(0, 10, "Hello everyone in color!!", 2);
    cw.refreshContainer();
    sleep(2);
    endwin();

    return 0;
}

它初始化颜色模式,但什么也不显示,就好像选择的对是黑色黑色。

【问题讨论】:

标签: c++ colors console ncurses


【解决方案1】:

运行代码(并使用 ncurses 的debug-trace feature 对其进行跟踪),只有一次调用init_pair,使用一对似乎来自未初始化值的数字,例如,7978 在这部分清单:

called {init_pair(0x193e250,7978,5,7)
return }0

快速浏览一下源代码就可以看出与此方法相对应:

/* PUBLIC METHODS */
int ColorWindow::addColorPair(int foreground, int background) {
        if(foreground < 0 || foreground > 7
                || background < 0 || background > 7)
                return -1; 

        init_pair(npairs, foreground, background);
        npairs++;

        return npairs-1;
}

并且npairs 在构造函数中永远不会设置为零。

您可能会发现 valgrind 对于查看此类问题很有用。

【讨论】:

  • 嗯,复制代码时出错了。我已经编辑了,所以现在它显示了我所有的代码。
猜你喜欢
  • 2016-04-14
  • 2023-03-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多