删除当前框并添加另一个框

Removing Current Box and Adding Another Box

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

UI Design

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

我尝试了什么?

  1. 我试过将两个盒子加到 1 window,但我做不到。

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

如何更改 window 中的框?

你应该使用 layouts!

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


正在创建布局:

layout1 = QHBoxLayout()

添加小部件:

layout1.addWidget(QPushButton('Text'))

Show/Hide:

layout1.show()
layout1.hide()

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

如果很好地理解它,就可以用它创建很棒的应用程序。

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

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

关于它的主要事情是,您创建一个堆栈,向其中添加 3 child。 每个 child 都是一个包含您需要的信息的框。 很难在这里解释所有这些,但是 Videos are showing you every thing you need to know about 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;
}

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

我们可以使用不同的 methods/functions 替换 window 中的容器。

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