【问题标题】:Removing Current Box and Adding Another Box删除当前框并添加另一个框
【发布时间】:2020-08-25 19:46:34
【问题描述】:

我想创建一个登录系统。我设计了这个 UI:

UI Design

当我点击登录按钮时,我应该删除当前框并添加包含登录表单的新框。

我尝试了什么?

  1. 我尝试将两个框添加到 1 个窗口,但我不能。

  2. 我创建了一个 Gtkoffscreenwindow,并在其中添加了我的登录表单。但我无法将其添加到我的主窗口中。

如何更改窗口中的框?

【问题讨论】:

    标签: python gtk pygtk glade


    【解决方案1】:

    我最喜欢的小部件之一是GtkStack

    如果一个人理解它很好,它可以用它创建很棒的应用程序。

    现在你的情况应该很清楚if you follow this Tutorials (抱歉他们在 C 中)是如何工作的。

    请查看This Demo 以了解 GtkStack 的运行情况。

    关于它的主要内容是,您创建了一个堆栈,并在其中添加了 3 个子级。 每个孩子都是一个盒子,里面装着你需要的信息。 在这里很难解释所有这些,但Videos 向您展示了您需要了解的有关GtkStack 的所有信息。

    编辑:

    好吧,如果你坚持要代码:

    #include <gtk/gtk.h>
    
    GtkWidget *createWindow         ( const gint width, const gint height, const gchar *const title );
    GtkWidget *create_login_box     ( GtkWidget *stack );
    GtkWidget *create_stack_box     ( GtkWidget **stack );
    GtkWidget *create_login_grid    ( GtkWidget *stack );
    GtkWidget *create_register_grid ( GtkWidget *stack );
    
    void login_clbk    ( GtkButton *button, GtkStack *stack );
    void main_clbk     ( GtkButton *button, GtkStack *stack );
    void register_clbk ( GtkButton *button, GtkStack *stack );
    
    void clicked_clbk ( GtkButton *button, GtkStack *stack );
    void load_css     ( void );
    void quit_clbk    ( void );
    
    int main ( void )
    {
        GtkWidget *window;
        GtkWidget *login_box;
        GtkWidget *login_grid;
        GtkWidget *register_grid;
    
        GtkWidget *stack_box;
        GtkWidget *stack;
    
        /// ***
        gtk_init ( NULL, NULL );
        load_css();
    
        /// *** Create a Window
        window = createWindow ( 300, 300, "GtkBin" );
    
        /// *** Create the Stack Box
        stack_box = create_stack_box ( &stack );
        gtk_container_add ( GTK_CONTAINER ( window ), stack_box );
    
        /// ***
        login_box     = create_login_box     ( stack );
        login_grid    = create_login_grid    ( stack );
        register_grid = create_register_grid ( stack );
    
        /// ***
        gtk_stack_add_named  ( GTK_STACK ( stack ), login_box,     "Main" );
        gtk_stack_add_named  ( GTK_STACK ( stack ), login_grid,    "Login" );
        gtk_stack_add_named  ( GTK_STACK ( stack ), register_grid, "Register" );
    
        /// ***
        gtk_stack_set_transition_type ( GTK_STACK ( stack ), GTK_STACK_TRANSITION_TYPE_SLIDE_DOWN );
        gtk_stack_set_transition_duration ( GTK_STACK ( stack ), 1000 );
        gtk_stack_set_interpolate_size ( GTK_STACK ( stack ), TRUE );
    
        /// ***
        gtk_widget_show_all ( window );
        gtk_main ();
    }
    
    void load_css ( void )
    {
        GtkCssProvider *provider;
        GdkDisplay     *display;
        GdkScreen      *screen;
        /// ***
        const gchar *css_style_file = "style.css";
        GFile *css_fp               = g_file_new_for_path ( css_style_file );
        GError *error               = 0;
        /// ***
        provider = gtk_css_provider_new ();
        display  = gdk_display_get_default ();
        screen   = gdk_display_get_default_screen ( display );
        /// ***
        gtk_style_context_add_provider_for_screen   ( screen, GTK_STYLE_PROVIDER ( provider ), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION );
        gtk_css_provider_load_from_file             ( provider, css_fp, &error );
        /// ***
    }
    
    GtkWidget *createWindow ( const gint width, const gint height, const gchar *const title )
    {
        GtkWidget *window;
        window = gtk_window_new ( GTK_WINDOW_TOPLEVEL );
        gtk_window_set_title ( GTK_WINDOW ( window ), title );
        g_signal_connect ( window, "destroy", gtk_main_quit, window );
        gtk_window_set_default_size ( GTK_WINDOW ( window ), width, height );
        gtk_container_set_border_width ( GTK_CONTAINER ( window ), 50 );
        return window;
    }
    
    GtkWidget *create_login_box ( GtkWidget *stack )
    {
        GtkWidget *box;
        GtkWidget *login_button;
        GtkWidget *register_button;
        GtkWidget *close_button;
    
        /// *** Create the Box
        box = gtk_box_new ( GTK_ORIENTATION_VERTICAL, 10 );
    
        /// *** Create the Buttons
        login_button    = gtk_button_new_with_label ( "Login" );
        register_button = gtk_button_new_with_label ( "Register" );
        close_button    = gtk_button_new_with_label ( "Close" );
    
        /// *** Add them to the Box
        gtk_box_pack_start ( GTK_BOX ( box ), login_button,    0, 0, 0 );
        gtk_box_pack_start ( GTK_BOX ( box ), register_button, 0, 0, 0 );
        gtk_box_pack_start ( GTK_BOX ( box ), close_button,    0, 0, 0 );
    
        /// ***
        g_signal_connect ( login_button,    "clicked", G_CALLBACK ( login_clbk ),    stack );
        g_signal_connect ( register_button, "clicked", G_CALLBACK ( register_clbk ), stack );
        g_signal_connect ( close_button,    "clicked", G_CALLBACK ( quit_clbk ),      NULL );
    
        /// *** Return the Box
        return box;
    }
    
    GtkWidget *create_login_grid ( GtkWidget *stack )
    {
        GtkWidget *grid;
        GtkWidget *login_button;
        GtkWidget *back_button;
    
        GtkWidget *label_username;
        GtkWidget *entry_username;
    
        GtkWidget *label_password;
        GtkWidget *entry_password;
    
        /// *** Create the Grid
        grid = gtk_grid_new();
    
        /// ***
        label_username = gtk_label_new ( "Username:" );
        label_password = gtk_label_new ( "Password:" );
    
        /// ***
        entry_username = gtk_entry_new();
        entry_password = gtk_entry_new();
    
        /// ***
        login_button = gtk_button_new_with_label ( "Login" );
        back_button  = gtk_button_new_with_label ( "Go to Main" );
    
        /// ***
        gtk_grid_attach ( GTK_GRID ( grid ), label_username, 0, 0, 1, 1 );
        gtk_grid_attach ( GTK_GRID ( grid ), entry_username, 1, 0, 1, 1 );
        gtk_grid_attach ( GTK_GRID ( grid ), label_password, 0, 1, 1, 1 );
        gtk_grid_attach ( GTK_GRID ( grid ), entry_password, 1, 1, 1, 1 );
        gtk_grid_attach ( GTK_GRID ( grid ), back_button,    0, 2, 1, 1 );
        gtk_grid_attach ( GTK_GRID ( grid ), login_button,   1, 2, 1, 1 );
    
        /// ***
        g_signal_connect ( back_button, "clicked", G_CALLBACK ( main_clbk ), stack );
    
        /// ***
        return grid;
    }
    
    GtkWidget *create_register_grid ( GtkWidget *stack )
    {
        GtkWidget *grid;
        GtkWidget *register_button;
        GtkWidget *back_button;
    
        GtkWidget *label_firstName;
        GtkWidget *entry_firstName;
    
        GtkWidget *label_lastName;
        GtkWidget *entry_lastName;
    
        GtkWidget *label_password;
        GtkWidget *entry_password;
    
        GtkWidget *label_street;
        GtkWidget *entry_street;
    
        GtkWidget *label_number;
        GtkWidget *entry_number;
    
        GtkWidget *label_email;
        GtkWidget *entry_email;
    
    
        /// *** Create the Grid
        grid = gtk_grid_new();
    
        /// ***
        label_firstName = gtk_label_new ( "First Name:" );
        label_lastName  = gtk_label_new ( "Last Name" );
        label_password  = gtk_label_new ( "Password:" );
        label_street    = gtk_label_new ( "Street:" );
        label_number    = gtk_label_new ( "Number:" );
        label_email     = gtk_label_new ( "Email:" );
    
        /// ***
        entry_firstName = gtk_entry_new();
        entry_lastName  = gtk_entry_new();
        entry_password  = gtk_entry_new();
        entry_street    = gtk_entry_new();
        entry_number    = gtk_entry_new();
        entry_email     = gtk_entry_new();
    
        /// ***
        register_button = gtk_button_new_with_label ( "Register" );
        back_button    = gtk_button_new_with_label ( "Back to Main" );
    
        /// ***
        gtk_grid_attach ( GTK_GRID ( grid ), label_firstName, 0, 0, 1, 1 );
        gtk_grid_attach ( GTK_GRID ( grid ), entry_firstName, 1, 0, 1, 1 );
    
        gtk_grid_attach ( GTK_GRID ( grid ), label_lastName,  0, 1, 1, 1 );
        gtk_grid_attach ( GTK_GRID ( grid ), entry_lastName,  1, 1, 1, 1 );
    
        gtk_grid_attach ( GTK_GRID ( grid ), label_password,  0, 2, 1, 1 );
        gtk_grid_attach ( GTK_GRID ( grid ), entry_password,  1, 2, 1, 1 );
    
        gtk_grid_attach ( GTK_GRID ( grid ), label_street,    0, 3, 1, 1 );
        gtk_grid_attach ( GTK_GRID ( grid ), entry_street,    1, 3, 1, 1 );
    
        gtk_grid_attach ( GTK_GRID ( grid ), label_number,    0, 4, 1, 1 );
        gtk_grid_attach ( GTK_GRID ( grid ), entry_number,    1, 4, 1, 1 );
    
        gtk_grid_attach ( GTK_GRID ( grid ), label_email,     0, 5, 1, 1 );
        gtk_grid_attach ( GTK_GRID ( grid ), entry_email,     1, 5, 1, 1 );
    
        gtk_grid_attach ( GTK_GRID ( grid ), back_button,     0, 6, 1, 1 );
        gtk_grid_attach ( GTK_GRID ( grid ), register_button, 1, 6, 1, 1 );
    
        /// ***
        g_signal_connect ( back_button, "clicked", G_CALLBACK ( main_clbk ), stack );
    
        /// ***
        return grid;
    }
    
    GtkWidget *create_stack_box ( GtkWidget **stack )
    {
        GtkWidget *box;
    
        /// *** Create the Box
        box = gtk_box_new ( GTK_ORIENTATION_VERTICAL, 10 );
    
        /// *** Create a Stack
        *stack = gtk_stack_new ();
        gtk_widget_set_halign ( *stack, GTK_ALIGN_CENTER );
        gtk_box_set_center_widget ( GTK_BOX ( box ), *stack );
    
        /// ***
        return box;
    }
    
    void main_clbk ( GtkButton *button, GtkStack *stack )
    {
        g_return_if_fail ( GTK_IS_BUTTON ( button ) );
        g_return_if_fail ( GTK_IS_STACK ( stack ) );
    
        gtk_stack_set_visible_child_full ( stack, "Main", GTK_STACK_TRANSITION_TYPE_SLIDE_DOWN );
        g_print ( "Switching to %s.\n", gtk_stack_get_visible_child_name ( stack ) );
    }
    
    void login_clbk ( GtkButton *button, GtkStack *stack )
    {
        g_return_if_fail ( GTK_IS_BUTTON ( button ) );
        g_return_if_fail ( GTK_IS_STACK ( stack ) );
    
    
        gtk_stack_set_visible_child_full ( stack, "Login", GTK_STACK_TRANSITION_TYPE_SLIDE_UP );
        g_print ( "Switching to %s.\n", gtk_stack_get_visible_child_name ( stack ) );
    }
    
    void register_clbk ( GtkButton *button, GtkStack *stack )
    {
        g_return_if_fail ( GTK_IS_BUTTON ( button ) );
        g_return_if_fail ( GTK_IS_STACK ( stack ) );
    
        gtk_stack_set_visible_child_full ( stack, "Register", GTK_STACK_TRANSITION_TYPE_SLIDE_UP );
        g_print ( "Switching to %s.\n", gtk_stack_get_visible_child_name ( stack ) );
    }
    
    void quit_clbk    ( void )
    {
        g_print ( "GoodBye\n" );
        gtk_main_quit();
    }
    

    CSS 文件:

    window
    {
        background-color:   #353535;
    }
    
    entry
    {
        background:         gray;
        color:              white;
        font-size:          15px;
    }
    
    label
    {
        color:              white;
        font-size:          12px;
        margin-right:       15px;
    }
    
    button
    {
        background:         #343434;
        border-color:       black;
        box-shadow:         none;
        margin:             10px;
    }
    
    button:hover
    {
        background:         red;
    }
    
    button:active
    {
        background:         black;
    }
    

    您需要检查它是否有错误,因为这是一种快速编码。 玩得开心!

    【讨论】:

    • 我回家后会发布?
    【解决方案2】:

    你应该使用layouts

    创建每个表单/布局后,您可以简单地隐藏包含按钮的布局,并显示包含表单的布局。
    还有更多的布局可以使用,我只提供了一个例子,请阅读文档!


    创建布局:

    layout1 = QHBoxLayout()
    

    添加小部件:

    layout1.addWidget(QPushButton('Text'))
    

    显示/隐藏:

    layout1.show()
    layout1.hide()
    

    【讨论】:

      【解决方案3】:

      我们可以使用不同的方法/功能替换窗口中的容器。

      #!/usr/bin/python3
      
      import gi
      gi.require_version("Gtk", "3.0")
      from gi.repository import Gtk
      
      class MainWindow(Gtk.Window):
          def __init__(self):
      
              # 1st we draw headerbar and put give choice
              # we have to replace vbox container 
              self.draw_main_window_headerbar()   # draw window
              self.ask_what_you_want()            # on startup ask what you want?
      
          def ask_what_you_want(self):
              self.vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing = 0)
              self.add(self.vbox)
              
              #1st button
              self.button1Login = Gtk.Button();
              self.button1Login.set_label("Login")
              self.vbox.pack_start(self.button1Login, False, False, 8)
              self.button1Login.connect("clicked", self.start_login)
      
              #2nd button
              self.button2Register = Gtk.Button();
              self.button2Register.set_label("Register")
              self.vbox.pack_start(self.button2Register, False, False, 8)
              self.button2Register.connect("clicked", self.start_register)
      
      
          def start_login(self, button):
                  
              # remove previous vbox container created by other methods
              self.remove(self.vbox)
      
              # Now add new vbox container
              self.vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing = 0)
              self.add(self.vbox)
      
              
              #hearbox title and subtitle can be changed 
              self.hb.props.title = "Login"
              self.hb.props.subtitle = "Welcome"
              
              #you can change/add pack widgets here
              self.label_login = Gtk.Label()
              self.label_login.set_label("Login: Enter your Username")
              self.vbox.pack_start(self.label_login, False, False, 0)
              
              #need to update after replacing vbox container           
              self.show_all()
              
         
          def start_register(self,button):
              # remove previous vbox container created by other methods
              self.remove(self.vbox)
      
              # Now add new vbox container
              self.vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing = 0)
              self.add(self.vbox)
              
              #hearbox title and subtitle can be changed 
              self.hb.props.title = "Register"
              self.hb.props.subtitle = "New User"
              
              #you can change/add pack widgets here
              self.label_register = Gtk.Label()
              self.label_register.set_label("Register: Crease User and Password")
              self.vbox.pack_start(self.label_register, False, False, 0)
              
              #need to update after replacing vbox container        
              self.show_all()
      
          def draw_main_window_headerbar(self):
              Gtk.Window.__init__(self, title="GPL3 Asif Ali Rizvan")
              self.hb = Gtk.HeaderBar()
              self.hb.set_show_close_button(True)
              self.hb.props.title = "Proje Basligi"
              self.hb.props.subtitle= "Ana Menu"
              self.set_titlebar(self.hb)
                     
              self.set_border_width(15)
              self.set_size_request(400,200)
              self.set_default_size(400,300)
              self.set_resizable(True)
              self.set_position(Gtk.WindowPosition.CENTER)
              
              #Setting Dark theme
              settings = Gtk.Settings.get_default()
              settings.set_property("gtk-application-prefer-dark-theme", True)
      
      
      
      # Main Program
      win = MainWindow()
      win.connect("destroy", Gtk.main_quit)
      win.show_all()
      Gtk.main()
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-11-09
        • 2015-03-21
        • 1970-01-01
        • 1970-01-01
        • 2012-03-09
        相关资源
        最近更新 更多