emre
emre

Reputation: 65

Removing Current Box and Adding Another Box

I want to create an login system. I designed this UI:

UI Design

When i click to login button, i should to remove current box and add new box that it contains login form.

What I tried?

  1. I tried adding two box to 1 window, but i cant.

  2. I created an Gtkoffscreenwindow, and i added my login form in this. But i cant added this to my main window.

How can i change the box in window?

Upvotes: 2

Views: 325

Answers (3)

fastrizwaan
fastrizwaan

Reputation: 290

We can replace Containers in the window, using different methods/functions. enter image description here

#!/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()

Upvotes: 1

Michi
Michi

Reputation: 5307

One of my Favorite Widget is GtkStack

If one understand it good it can create awesome application with it.

Now in your case it should be clear how is working if you follow this Tutorials ( sorry they are in C).

Please check This Demo to see GtkStack in action.

Main thing about it, is that you create a Stack, where you add 3 child to it. Every child is a box containing the information you need. It will be to difficult to explain all this in here, but the Videos are showing you every thing you need to know about GtkStack.

EDIT:

well, if you insist for the code:

#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 File:

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;
}

You need to check it for errors, because this was a fast coding. Have fun!

Upvotes: 2

nagyl
nagyl

Reputation: 1644

You should use layouts!

After each form/layout is created, you can simply hide the layout that contains the buttons, and show the one contains the form.
There are more layouts to use, I provided just one example, please read the docs!


Creating a layout:

layout1 = QHBoxLayout()

Adding the widgets:

layout1.addWidget(QPushButton('Text'))

Show/Hide:

layout1.show()
layout1.hide()

Upvotes: 2

Related Questions