2017-09-14 126 views
0

我嘗試用gtkmm創建一個窗口,其中有兩個文本視圖。文本視圖應排列爲垂直分屏。 就像是: Split screen用GTK +/gtkmm Grid分割屏幕

後來我想能夠在Emacs一次又一次分割屏幕的垂直和水平並調整分離區域,等等。

我認爲一個簡單的分屏應該很容易,但我已經卡在那裏了。 我曾考慮過使用Gtk :: Grid作爲佈局容器,每次用戶想要分割屏幕時,我想添加一行或一列,並在新創建的區域添加一個新的文本視圖。

這裏是我的代碼:

main.cc

#include <gtkmm/application.h> 

#include "examplewindow.h" 

int main(int argc, char *argv[]) 
{ 
    auto app = Gtk::Application::create(argc, argv, "org.gtkmm.example"); 

    ExampleWindow window; 

    //Shows the window and returns when it is closed. 
    return app->run(window); 
} 

examplewindow.h

#ifndef GTKMM_EXAMPLEWINDOW_H 
#define GTKMM_EXAMPLEWINDOW_H 

#include <gtkmm.h> 

class ExampleWindow : public Gtk::Window 
{ 
public: 
    ExampleWindow(); 
    virtual ~ExampleWindow(); 

protected: 
    Gtk::Grid main_grid; 
    Gtk::ScrolledWindow scrolled_window1; 
    Gtk::ScrolledWindow scrolled_window2; 
    Gtk::TextView text_view1; 
    Gtk::TextView text_view2; 

    Glib::RefPtr<Gtk::TextBuffer> text_buffer1, text_buffer2; 

    void fill_buffers(); 
}; 

#endif //GTKMM_EXAMPLEWINDOW_H 

examplewindow.cc

#include "examplewindow.h" 

ExampleWindow::ExampleWindow() { 
    set_title("Gtk splitted textviews"); 
    set_border_width(12); 

    add(main_grid); 

    scrolled_window1.add(text_view1); 
    scrolled_window1.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); 
    scrolled_window2.add(text_view2); 
    scrolled_window1.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); 

    main_grid.insert_column(0); 
    main_grid.attach(scrolled_window1, 0, 0, 1, 1); 
    //scrolled_window1.set_hexpand(true); 
    //scrolled_window1.set_vexpand(true); 

    main_grid.attach(scrolled_window2, 1, 0, 1, 1); 
    //scrolled_window1.set_hexpand(true); 
    //scrolled_window1.set_vexpand(true); 

    fill_buffers(); 
    text_view1.set_buffer(text_buffer1); 
    text_view2.set_buffer(text_buffer2); 

    show_all_children(); 
} 

ExampleWindow::~ExampleWindow() {} 

void ExampleWindow::fill_buffers() { 
    text_buffer1 = Gtk::TextBuffer::create(); 
    text_buffer1->set_text("This is the text from TextBuffer #1."); 

    text_buffer2 = Gtk::TextBuffer::create(); 
    text_buffer2->set_text(
      "This is some alternative text, from TextBuffer #2."); 

} 

構建具有:

g++ examplewindow.cc main.cc -o splittv `pkg-config gtkmm-3.0 --cflags --libs` 

這將產生的結果: Too small text views

文本的意見顯然是小。如果我在兩個文本視圖上設置了hexpand和vexpand爲true,text_view1會抑制text_view2。

+1

對於分割屏幕,我將開始尋找到['GtkPaned'](https://developer.gnome.org/gtk3 /stable/GtkPaned.html) – Gerhardh

+0

您的代碼中存在拼寫錯誤。爲scrolled_window1設置十六進制和vexpand兩次。也許你想要改變爲scrolled_window2。 – JohnKoch

回答

0

由於@Gerhardh在評論建議你可以使用GtkPaned

#include <gtkmm.h> 
#include <memory> 
#include <string> 

struct Body 
{ 
    inline static int i=0; 
    Gtk::Box Box; 
    Gtk::Button SplitHButton, SplitVButton, CloseButton; 
    Gtk::Label Label; 
    Body() 
    { 
     SplitHButton.set_label("h"); 
     SplitVButton.set_label("v"); 
     Label.set_text(std::to_string(i++)); 
     CloseButton.set_label("c"); 
     Box.add(SplitHButton); 
     Box.add(SplitVButton); 
     Box.add(Label); 
     Box.add(CloseButton); 
     Box.show_all(); 
    } 
}; 

struct Pane 
{ 
    Gtk::Paned PaneWidget; 
    std::shared_ptr<Pane> ChildPane1, ChildPane2; 
    Body Body1, Body2; 
    Pane(Gtk::Orientation orientation=Gtk::ORIENTATION_HORIZONTAL): 
     PaneWidget(orientation) 
    { 
     PaneWidget.add1(Body1.Box); 
     PaneWidget.add2(Body2.Box); 

     Body1.SplitHButton.signal_clicked().connect([this]{Split(ChildPane1, Gtk::ORIENTATION_HORIZONTAL, Body1, true);}); 
     Body1.SplitVButton.signal_clicked().connect([this]{Split(ChildPane1, Gtk::ORIENTATION_VERTICAL, Body1, true);}); 
     Body2.SplitHButton.signal_clicked().connect([this]{Split(ChildPane2, Gtk::ORIENTATION_HORIZONTAL, Body2, false);}); 
     Body2.SplitVButton.signal_clicked().connect([this]{Split(ChildPane2, Gtk::ORIENTATION_VERTICAL, Body2, false);}); 

     PaneWidget.show_all(); 
    } 

    void Split(std::shared_ptr<Pane>& pane, Gtk::Orientation orientation, Body& body, bool leftTop) 
    { 
     pane = std::make_shared<Pane>(orientation); 
     PaneWidget.remove(body.Box); 
     if(leftTop) 
      PaneWidget.add1(pane->PaneWidget); 
     else 
      PaneWidget.add2(pane->PaneWidget); 

     auto lambda = [&]{ 
       PaneWidget.remove(pane->PaneWidget); 
       if(leftTop) 
        PaneWidget.add1(body.Box); 
       else 
        PaneWidget.add2(body.Box); 
       PaneWidget.show_all(); 
       pane.reset(); 
     }; 

     pane->Body1.CloseButton.signal_clicked().connect(lambda); 
     pane->Body2.CloseButton.signal_clicked().connect(lambda); 
    } 
}; 

int main() 
{ 
    auto GtkApp = Gtk::Application::create(); 
    Gtk::Window w; 
    Pane p; 
    w.add(p.PaneWidget); 
    w.resize(800,600); 
    w.show_all(); 
    GtkApp->run(w); 
    return 0; 
} 

enter image description here