Reputation: 65
I want to create an login system. I designed this UI:
When i click to login button, i should to remove current box and add new box that it contains login form.
I tried adding two box to 1 window, but i cant.
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
Reputation: 290
We can replace Containers in the window, using different methods/functions.
#!/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
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
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