tags: python fltk title: FLTK Examples 01 # Text Display ```py #!/usr/bin/env python from fltk import * import sys import os def quit(): win = Fl.first_window() while win := Fl.first_window(): win.hide() class MyWindow(Fl_Window): def __init__(self,width,height,textsize=14,text="",margin=20): super().__init__(width,height) coords = (margin,margin,width-2*margin,height-2*margin) self.mytext = Fl_Text_Display(*coords) self.mytext.textsize(textsize) self.bgcolor = fl_rgb_color(0,0,30) self.fgcolor = fl_rgb_color(255,255,130) self.mytext.textcolor(self.fgcolor) self.mytext.color(self.bgcolor) self.textbuffer = Fl_Text_Buffer() self.textbuffer.text(text) self.mytext.buffer(self.textbuffer) self.add(self.mytext) self.end() def handle(self,x): match x: case 12: return self.handlekey() return super().handle(x) def handlekey(self): k = Fl.event_key() t = Fl.event_text() print("MyWindow","key",k,"text",t) match t.lower(): case "q": print("Window Quit") quit() return 1 return 0 def main(): args = sys.argv[1:] switches = [] other = [] for x in args: if x[0] == "-": switches.append(x) else: other.append(x) # we pass all switches to the Fl handler, # but all other text we want to deal with. argv = [sys.argv[0]] + switches # configure using environment variables # rather than having a more elaborate arg processor geom = os.getenv("GEOMETRY","400,300") margin = os.getenv("MARGIN","20") textsize = os.getenv("TEXTSIZE","14") # validate env variables for sanity try: width, height = [ int(x) for x in geom.split(",") ] except ValueError: print("Bad GEOMETRY",geom) exit(1) try: textsize = int(textsize) except ValueError: print("Bad TEXTSIZE",textsize) exit(1) try: margin = int(margin) if margin < 0: raise ValueError() coords = (margin,margin,width-2*margin,height-2*margin) if coords[2] <= 0 or coords[3] <= 0: raise ValueError() except ValueError: print("Bad MARGIN",margin) exit(1) # the text that will be displayed: # the result of concatenating command line args # one per line and any text piped in. if not sys.stdin.isatty(): other.append(sys.stdin.read()) text = "\n".join(other) window = MyWindow(width,height,textsize=textsize,text=text,margin=margin) window.show(argv) Fl.run() print("Finished") if __name__ == "__main__": main() ``` A similar C++ version is this. It also illustrates how to turn naked pointers of old style C++ into `std::unique_ptr`s. ```cpp /* build with g++ -o fl_text_display fl_text_display.cpp -lfltk -lX11 -lm */ // for unique_ptr and make_unique #include // for cout and cin #include // Needed for seeing if stdin is a pipe or a tty #include #include #include #include #include #include class MyWindow : public Fl_Window { protected: std::unique_ptr m_text_display; std::unique_ptr m_text_buffer; int m_width; int m_height; int m_margin; public: virtual ~MyWindow() { } MyWindow(int width, int height, int margin) : Fl_Window(width,height) { m_width = width; m_height = height; m_margin = margin; if( (2 * m_margin) > m_width || (2 * m_margin) > m_height ) { m_margin = 0; } m_text_display = std::make_unique(m_margin,m_margin,m_width-2*m_margin,m_height-2*m_margin); m_text_buffer = std::make_unique(); m_text_display->buffer(*m_text_buffer); m_text_display->textcolor(fl_rgb_color(255,255,130)); m_text_display->color(fl_rgb_color(0,0,30)); end(); } void text(std::string txt) { m_text_buffer->text(txt.c_str()); } int handle(int x) { switch(x) { case 12: return handlekey(); } return 0; } int handlekey() { switch(Fl::event_key()) { case 'q': case 'Q': quit(); return 1; } return 0; } void quit() { Fl_Window* win; while( win = Fl::first_window() ) { win->hide(); } } private: }; std::string get_text() { if( isatty(fileno(stdin)) ) return std::string(); std::istreambuf_iterator begin(std::cin), end; std::string buf(begin, end); return buf; } int main(int argc, char **argv) { std::string text = get_text(); std::unique_ptr window = std::make_unique(400,400,10); window->text(text); window->show(argc, argv); return Fl::run(); } ```