草庐IT

【esp32&lvgl】-2.6 #lvgl-多页面(screen)设定/切换

weixin_43326110 2024-03-13 原文

目录

一、前言

二、实现原理

2.1 各个screen的定义及初始化

2.2 各个screen内的内容绘制

2.3 页面切换的events_handler

三、代码实现

3.1 PageManage库

3.2 Page_mainMenu库(界面)

3.3 Page_wifi库(界面)

参考文献


一、前言

        利用lvgl框架绘制GUI免不了需要实现多个页面的切换,毕竟把所有功能和接口都放在一页上有些不太优雅,而且对于嵌入式硬件的小屏幕也有些过于困难。因此这里就需要实现多个页面(或者说lvgl里的screen)及其互相切换。

二、实现原理

        在lvgl中实现多个页面间的切换有多种方案,已经有大佬简单总结过

  • 通过LV_OBJ_FLAG_HIDDEN隐藏属性实现页面切换
  • 在回调函数中,创建新窗口并删除旧窗口
  • 使用函数lv_scr_load_anim和lv_scr_load加载和切换屏幕

        在本文中,个人使用了第三种方案,但是相比较于上述文章中大佬的代码有一些改动,参考了lvgl官方的lv_demo_keypad_encoder代码,将各个环节的耦合性降低,模块化程度提升方便后续拓展。 这一方案主要包括三个部分:

  • 各个screen的定义及初始化
  • 各个screen内的内容绘制
  • 页面切换的events_handler

2.1 各个screen的定义及初始化

         在lvgl中screen就是没有父对象的特殊obj,可以通过

    lv_obj_t * scr1 = lv_obj_create(NULL);

创建。基于此,我们可以创建多块屏幕作为不同界面的容器。当然由于没有通过默认的屏幕lv_scr_act()作为父类继承屏幕的属性,这里需要详细设定屏幕的属性(主要是屏幕的尺寸等)。此外在完成各screen的定义后记得把默认界面及其内的各控件加载上(指将各控件加入group和输入设备联系上)。

static void scrInit(){
    Scr_mainMenu = lv_obj_create(NULL);
    lv_obj_clean(Scr_mainMenu);    
    lv_obj_remove_style_all(Scr_mainMenu);
    lv_obj_set_style_bg_opa(Scr_mainMenu, LV_OPA_COVER, 0);//0不透明
    lv_obj_set_style_bg_color(Scr_mainMenu, lv_color_black(), 0);
    lv_obj_set_size(Scr_mainMenu, LV_HOR_RES, LV_VER_RES);   

    Scr_wifi = lv_obj_create(NULL);
    lv_obj_clean(Scr_wifi);
    lv_obj_remove_style_all(Scr_wifi);
    lv_obj_set_style_bg_opa(Scr_wifi, LV_OPA_COVER, 0);//0不透明
    lv_obj_set_style_bg_color(Scr_wifi, lv_color_black(), 0);
    lv_obj_set_size(Scr_wifi, LV_HOR_RES, LV_VER_RES);   

    lv_scr_load(Scr_mainMenu);    
    objsLoad(Scr_mainMenu);
}

screen的加载只需要使用lv_scr_load即可实现加载界面。但是对于界面内各控件的加载就需要专门写一个函数来实现了,即objsLoad函数。这个函数可以调用个界面内的控件组成的struct,循环加入group,具体如何实现这一struct可以参看2.2.

static void objsLoad(lv_obj_t * Scr){
    size_t size = 0;
    lv_obj_t ** objs = NULL;

    if(Scr == getScr_wifi()){
        size = sizeof(wifi_objs);
        objs = (lv_obj_t**) &wifi_objs;
    }
    if(Scr == getScr_mainMenu()){
        size = sizeof(mainMenu_objs);
        objs = (lv_obj_t**) &mainMenu_objs;
    }
    for(uint32_t i = 0; i < size / sizeof(lv_obj_t *); i++) {
        if(objs[i] == NULL) continue;
        lv_group_add_obj(group_Default, objs[i]);
    }
}

2.2 各个screen内的内容绘制

        内容绘制就比较容易理解了,按照界面上所需的内容依次绘制即可。这里根据我的使用需求我在界面1画了几个按钮,其中一个界面是进入另一个界面的入口。详细代码看第三章,这里不再赘述。简单说两个绘制界面中遇到的问题:

  • 各style最好在创建obj之前一并进行设定好,否则可能会出现style显示错误的情况
  • label 上的字体(包括符号)大小需要去espidf的界面把用到的字体大小激活
图一-ESP-IDF界面内激活字符大小

 另外为了便于界面内各控件的加载,记得把所有需要与输入设备绑定的控件放到一个struct内便于调用,这里参考了lvgl的官方lv_demo_keypad_encoder代码

struct {
    lv_obj_t * btn_wifi;
    lv_obj_t * btn_setting;
    lv_obj_t * btn_crctrl;
}mainMenu_objs;  //需要后续操作的界面内的控件

2.3 页面切换的events_handler

页面切换的管理通过一个回调函数实现:

void event_handler_swtichPage(lv_event_t * e){
    lv_obj_t * next_page = lv_event_get_user_data(e);

    lv_group_remove_all_objs(group_Default);

    lv_scr_load_anim(next_page, LV_SCR_LOAD_ANIM_FADE_ON, 10, 0, false);
    objsLoad(next_page);
}

 先把group内的各个组件删去,然后加载目标界面(通过传参方式实现)然后把目标界面的各个组件加载进group内。 传参的方式如下:

lv_obj_add_event_cb(mainMenu_objs.btn_wifi, event_handler_swtichPage, LV_EVENT_CLICKED, Scr_wifi);    

三、代码实现

3.1 PageManage库

包含各个页面的设定及初始化,页面切换的回调函数。

PageManage.h

#ifndef PAGEMANAGE_H
#define PAGEMANAGE_H

/*********************
 *      INCLUDES
 *********************/
#include "lvgl.h"
#include "PageManage.h"
#include "Page_wifi.h"
#include "Page_mainMenu.h"

/*********************
 *      DEFINES
 *********************/

/**********************
 *      TYPEDEFS
 **********************/

/**********************
 * GLOBAL PROTOTYPES
 **********************/
lv_obj_t *Scr_mainMenu;
lv_obj_t *Scr_wifi;

void PageManage_Init();

void event_handler_swtichPage(lv_event_t * e);
/**********************
 *      MACROS
 **********************/

#endif

PageManage.c


/*********************
 *      INCLUDES
 *********************/
#include "PageManage.h"

/*********************
 *      DEFINES
 *********************/

/**********************
 *      TYPEDEFS
 **********************/

/**********************
 *  STATIC PROTOTYPES
 **********************/
static void scrInit();
static void objsLoad(lv_obj_t * Scr);//???通过设定自定义类或者什么统一页面的管理

/**********************
 *  STATIC VARIABLES
 **********************/
static lv_group_t*  group_Default;

/**********************
 *      MACROS
 **********************/

/**********************
 *   GLOBAL FUNCTIONS
 **********************/
void PageManage_Init(){
    group_Default = lv_group_get_default();
    Scr_mainMenu = lv_obj_create(NULL);
    Scr_wifi = lv_obj_create(NULL);

    scrInit();
}

void event_handler_swtichPage(lv_event_t * e){
    lv_obj_t * next_page = lv_event_get_user_data(e);

    lv_group_remove_all_objs(group_Default);

    lv_scr_load_anim(next_page, LV_SCR_LOAD_ANIM_FADE_ON, 10, 0, false);
    objsLoad(next_page);
}

/**********************
 *   STATIC FUNCTIONS
 **********************/
static void scrInit(){
    lv_obj_clean(Scr_mainMenu);    
    lv_obj_remove_style_all(Scr_mainMenu);
    lv_obj_set_style_bg_opa(Scr_mainMenu, LV_OPA_COVER, 0);//0不透明
    lv_obj_set_style_bg_color(Scr_mainMenu, lv_color_black(), 0);
    lv_obj_set_size(Scr_mainMenu, LV_HOR_RES, LV_VER_RES);   

    lv_obj_clean(Scr_wifi);
    lv_obj_remove_style_all(Scr_wifi);
    lv_obj_set_style_bg_opa(Scr_wifi, LV_OPA_COVER, 0);//0不透明
    lv_obj_set_style_bg_color(Scr_wifi, lv_color_black(), 0);
    lv_obj_set_size(Scr_wifi, LV_HOR_RES, LV_VER_RES);   

    lv_scr_load(Scr_mainMenu);    
    objsLoad(Scr_mainMenu);

}

static void objsLoad(lv_obj_t * Scr){
    size_t size = 0;
    lv_obj_t ** objs = NULL;

    if(Scr == Scr_wifi){
        size = sizeof(wifi_objs);
        objs = (lv_obj_t**) &wifi_objs;
    }
    if(Scr == Scr_mainMenu){
        size = sizeof(mainMenu_objs);
        objs = (lv_obj_t**) &mainMenu_objs;
    }
    for(uint32_t i = 0; i < size / sizeof(lv_obj_t *); i++) {
        if(objs[i] == NULL) continue;
        lv_group_add_obj(group_Default, objs[i]);
    }
}

3.2 Page_mainMenu库(界面)

Page_mainMenu.h

#ifndef PAGE_MAINMENU_H
#define PAGE_MAINMENU_H

/*********************
 *      INCLUDES
 *********************/
#include "lvgl.h"
#include "config.h"
#include "PageManage.h"

/*********************
 *      DEFINES
 *********************/

/**********************
 *      TYPEDEFS
 **********************/

/**********************
 * GLOBAL PROTOTYPES
 **********************/
struct {
    lv_obj_t * btn_wifi;
    lv_obj_t * btn_setting;
    lv_obj_t * btn_crctrl;
}mainMenu_objs;  //需要后续操作的界面内的控件

/**
 * @brief 导入mainMenu界面
 * 
 */
void mainMenu();

/**********************
 *      MACROS
 **********************/

#endif

Page_mainMenu.c

/*********************
 *      INCLUDES
 *********************/
#include "Page_mainMenu.h"

/*********************
 *      DEFINES
 *********************/

/**********************
 *      TYPEDEFS
 **********************/

/**********************
 *  STATIC PROTOTYPES
 **********************/

/**
 * @brief 初始化main menu用到的lv_style
 * 
 */
static void styleInit();

/**********************
 *  STATIC VARIABLES
 **********************/
/*lv_style*/
static lv_style_t style_btn_wifi;
static lv_style_t style_btn_wifi_focused;
static lv_style_t style_btn_wifi_pressed;
static lv_style_t style_btn_setting;
static lv_style_t style_btn_setting_focused;
static lv_style_t style_btn_setting_pressed;
static lv_style_t style_btn_crctrl;
static lv_style_t style_btn_crctrl_focused;
static lv_style_t style_btn_crctrl_pressed;

/*lv_opa*/
static lv_opa_t opa_default = LV_OPA_COVER;
static lv_opa_t opa_focused = LV_OPA_60;
static lv_opa_t opa_pressed = LV_OPA_20;



/**********************
 *      MACROS
 **********************/

/**********************
 *   GLOBAL FUNCTIONS
 **********************/
void mainMenu(){
    /*style初始化*/
    styleInit();
    
    /*屏幕*/
    lv_obj_t *scr = Scr_mainMenu;

    /*logo*/
    lv_obj_t *img1 = lv_img_create(scr);
    lv_img_set_src(img1,"S:/image/tju_120.bin");
    lv_obj_align(img1, LV_ALIGN_TOP_MID, 0, 30);

    /*buton*/
    //-----create buton-wifi-----//
    //创建btn对象
    mainMenu_objs.btn_wifi = lv_btn_create(scr);
    lv_obj_remove_style_all(mainMenu_objs.btn_wifi);
    //修改尺寸&位置
    lv_obj_set_size(mainMenu_objs.btn_wifi, 75, 75);
    lv_obj_align(mainMenu_objs.btn_wifi, LV_ALIGN_BOTTOM_LEFT, 5, -5);
    //把style附加到btn对象
    lv_obj_add_style(mainMenu_objs.btn_wifi, &style_btn_wifi,LV_STATE_DEFAULT);
    lv_obj_add_style(mainMenu_objs.btn_wifi, &style_btn_wifi_focused,LV_STATE_FOCUSED);
    lv_obj_add_style(mainMenu_objs.btn_wifi, &style_btn_wifi_pressed,LV_STATE_PRESSED);
    //增加label
    lv_obj_t *wifi_label = lv_label_create(mainMenu_objs.btn_wifi);
    lv_label_set_text(wifi_label, LV_SYMBOL_WIFI);
    lv_obj_set_style_text_font(wifi_label, &lv_font_montserrat_30, 0);
    lv_obj_set_style_text_color(wifi_label, lv_color_white(), 0);
    lv_obj_center(wifi_label);
    //按键触发事件
    lv_obj_add_event_cb(mainMenu_objs.btn_wifi, event_handler_swtichPage, LV_EVENT_CLICKED, Scr_wifi);
    
    //-----create setting btn-----//
    //创建btn对象
    mainMenu_objs.btn_setting = lv_btn_create(scr);
    lv_obj_remove_style_all(mainMenu_objs.btn_setting);
    //修改尺寸&位置
    lv_obj_set_size(mainMenu_objs.btn_setting, 75, 75);
    lv_obj_align(mainMenu_objs.btn_setting, LV_ALIGN_BOTTOM_RIGHT, -5, -5);
    //把style附加到btn对象
    lv_obj_add_style(mainMenu_objs.btn_setting, &style_btn_setting,LV_STATE_DEFAULT);
    lv_obj_add_style(mainMenu_objs.btn_setting, &style_btn_setting_focused,LV_STATE_FOCUSED);
    lv_obj_add_style(mainMenu_objs.btn_setting, &style_btn_setting_pressed,LV_STATE_PRESSED);
    //增加label
    lv_obj_t *setting_label = lv_label_create(mainMenu_objs.btn_setting);
    lv_label_set_text(setting_label , LV_SYMBOL_SETTINGS);
    lv_obj_set_style_text_font(setting_label , &lv_font_montserrat_30, 0);
    lv_obj_set_style_text_color(setting_label , lv_color_white(), 0);
    lv_obj_center(setting_label);

    //-----create crctrl btn-----/
    //创建btn对象
    mainMenu_objs.btn_crctrl = lv_btn_create(scr);
    lv_obj_remove_style_all(mainMenu_objs.btn_crctrl);
    //修改尺寸&位置
    lv_obj_set_size(mainMenu_objs.btn_crctrl, 160, 60);
    lv_obj_align(mainMenu_objs.btn_crctrl, LV_ALIGN_CENTER, 0, 40);
    //把style附加到btn对象
    lv_obj_add_style(mainMenu_objs.btn_crctrl, &style_btn_crctrl,LV_STATE_DEFAULT);
    lv_obj_add_style(mainMenu_objs.btn_crctrl, &style_btn_crctrl_focused,LV_STATE_FOCUSED);
    lv_obj_add_style(mainMenu_objs.btn_crctrl, &style_btn_crctrl_pressed,LV_STATE_PRESSED);
    //增加label
    lv_obj_t *crctrl_label = lv_label_create(mainMenu_objs.btn_crctrl);
    lv_label_set_text(crctrl_label , "CRCTRL");
    lv_obj_set_style_text_font(crctrl_label , &lv_font_montserrat_30, 0);
    lv_obj_set_style_text_color(crctrl_label , lv_color_white(), 0);
    lv_obj_center(crctrl_label);
}


/**********************
 *   STATIC FUNCTIONS
 **********************/
static void styleInit(){
    //-----style-btn-wifi-----//
    //style-默认
    lv_style_init(&style_btn_wifi);

    lv_style_set_radius(&style_btn_wifi,10);    
    lv_style_set_bg_color(&style_btn_wifi,lv_color_hex(MY_COLOR_WIFI_BTN));
    lv_style_set_bg_opa(&style_btn_wifi,opa_default);
    //style-选中
    lv_style_init(&style_btn_wifi_focused);

    lv_style_set_radius(&style_btn_wifi_focused,10);    
    lv_style_set_bg_color(&style_btn_wifi_focused,lv_color_hex(MY_COLOR_WIFI_BTN));
    lv_style_set_bg_opa(&style_btn_wifi_focused,opa_focused);
    //style-点击
    lv_style_init(&style_btn_wifi_pressed);

    lv_style_set_radius(&style_btn_wifi_pressed,10);    
    lv_style_set_bg_color(&style_btn_wifi_pressed,lv_color_hex(MY_COLOR_WIFI_BTN));
    lv_style_set_bg_opa(&style_btn_wifi_pressed,opa_pressed);

    //-----style-btn-setting-----//
    //style-默认
    lv_style_init(&style_btn_setting);

    lv_style_set_radius(&style_btn_setting,10);
    lv_style_set_bg_color(&style_btn_setting,lv_color_hex(MY_COLOR_SETTING_BTN));
    lv_style_set_bg_opa(&style_btn_setting,opa_default);
    //style-选中
    lv_style_init(&style_btn_setting_focused);

    lv_style_set_radius(&style_btn_setting_focused,10);
    lv_style_set_bg_color(&style_btn_setting_focused,lv_color_hex(MY_COLOR_SETTING_BTN));
    lv_style_set_bg_opa(&style_btn_setting_focused,opa_focused);
    //style-点击
    lv_style_init(&style_btn_setting_pressed);

    lv_style_set_radius(&style_btn_setting_pressed,10);
    lv_style_set_bg_color(&style_btn_setting_pressed,lv_color_hex(MY_COLOR_SETTING_BTN));
    lv_style_set_bg_opa(&style_btn_setting_pressed,opa_pressed);
    
    //-----style-btn-crctrl-----//
    //style-默认
    lv_style_init(&style_btn_crctrl);

    lv_style_set_radius(&style_btn_crctrl,10);
    lv_style_set_bg_color(&style_btn_crctrl,lv_color_hex(MY_COLOR_CRCTRL_BTN));
    lv_style_set_bg_opa(&style_btn_crctrl,opa_default);
    //style-选中
    lv_style_init(&style_btn_crctrl_focused);

    lv_style_set_radius(&style_btn_crctrl_focused,10);
    lv_style_set_bg_color(&style_btn_crctrl_focused,lv_color_hex(MY_COLOR_CRCTRL_BTN));
    lv_style_set_bg_opa(&style_btn_crctrl_focused,opa_focused);
    //style-点击
    lv_style_init(&style_btn_crctrl_pressed);

    lv_style_set_radius(&style_btn_crctrl_pressed,10);
    lv_style_set_bg_color(&style_btn_crctrl_pressed,lv_color_hex(MY_COLOR_CRCTRL_BTN));
    lv_style_set_bg_opa(&style_btn_crctrl_pressed,opa_pressed);

}

3.3 Page_wifi库(界面)

Page_wifi.h

#ifndef PAGE_WIFI_H
#define PAGE_WIFI_H

/*********************
 *      INCLUDES
 *********************/
#include "lvgl.h"
#include "config.h"
#include "PageManage.h"

/*********************
 *      DEFINES
 *********************/

/**********************
 *      TYPEDEFS
 **********************/

/**********************
 * GLOBAL PROTOTYPES
 **********************/
struct {
    lv_obj_t * btn_back;
}wifi_objs;

/**
 * @brief 导入mainMenu界面
 * 
 */
void wifiPage_Init();

/**********************
 *      MACROS
 **********************/

#endif

Page_wifi.c

/*********************
 *      INCLUDES
 *********************/
#include "Page_wifi.h"

/*********************
 *      DEFINES
 *********************/

/**********************
 *      TYPEDEFS
 **********************/

/**********************
 *  STATIC PROTOTYPES
 **********************/

/**
 * @brief 初始化main menu用到的lv_style
 * 
 */
static void styleInit();

/**********************
 *  STATIC VARIABLES
 **********************/
/*lv_style*/
static lv_style_t style_btn_back;
static lv_style_t style_btn_back_focused;
static lv_style_t style_btn_back_pressed;

/*lv_opa*/
static lv_opa_t opa_default = LV_OPA_COVER;
static lv_opa_t opa_focused = LV_OPA_60;
static lv_opa_t opa_pressed = LV_OPA_20;

/**********************
 *      MACROS
 **********************/

/**********************
 *   GLOBAL FUNCTIONS
 **********************/
void wifiPage_Init(){
    /*style初始化*/
    styleInit();
    
    /*屏幕*/
    lv_obj_t *scr = Scr_wifi;

    /*buton*/
    //-----create buton-wifi-----//
    //创建btn对象
    wifi_objs.btn_back = lv_btn_create(scr);
    lv_obj_remove_style_all(wifi_objs.btn_back);
    //修改尺寸&位置
    lv_obj_set_size(wifi_objs.btn_back, 75, 75);
    lv_obj_align(wifi_objs.btn_back, LV_ALIGN_CENTER, 0, 0);
    //把style附加到btn对象
    lv_obj_add_style(wifi_objs.btn_back, &style_btn_back,LV_STATE_DEFAULT);
    lv_obj_add_style(wifi_objs.btn_back, &style_btn_back_focused,LV_STATE_FOCUSED);
    lv_obj_add_style(wifi_objs.btn_back, &style_btn_back_pressed,LV_STATE_PRESSED);
    //增加label
    lv_obj_t *back_label = lv_label_create(wifi_objs.btn_back);
    lv_label_set_text(back_label, LV_SYMBOL_LEFT);
    lv_obj_set_style_text_font(back_label, &lv_font_montserrat_30, 0);
    lv_obj_set_style_text_color(back_label, lv_color_white(), 0);
    lv_obj_center(back_label);
    //按键触发事件
    lv_obj_add_event_cb(wifi_objs.btn_back, event_handler_swtichPage, LV_EVENT_CLICKED, Scr_mainMenu);
}

/**********************
 *   STATIC FUNCTIONS
 **********************/
static void styleInit(){
    //-----style-btn-back-----//
    //style-默认
    lv_style_init(&style_btn_back);

    lv_style_set_radius(&style_btn_back,10);    
    lv_style_set_bg_color(&style_btn_back,lv_color_hex(MY_COLOR_WIFI_BTN));
    lv_style_set_bg_opa(&style_btn_back,opa_default);
    //style-选中
    lv_style_init(&style_btn_back_focused);

    lv_style_set_radius(&style_btn_back_focused,10);    
    lv_style_set_bg_color(&style_btn_back_focused,lv_color_hex(MY_COLOR_WIFI_BTN));
    lv_style_set_bg_opa(&style_btn_back_focused,opa_focused);
    //style-点击
    lv_style_init(&style_btn_back_pressed);

    lv_style_set_radius(&style_btn_back_pressed,10);    
    lv_style_set_bg_color(&style_btn_back_pressed,lv_color_hex(MY_COLOR_WIFI_BTN));
    lv_style_set_bg_opa(&style_btn_back_pressed,opa_pressed);
}

参考文献

(25条消息) LVGL V8应用——通过按键切换页面_临界msp的博客-CSDN博客_lvgl页面切换

https://github.com/lvgl/lv_demos/tree/3f41b7d18ec0bf55edb80058c7486727bbbd8a95/src/lv_demo_keypad_encoder

Objects(对象) — 百问网LVGL中文教程文档 文档 (100ask.net)

有关【esp32&lvgl】-2.6 #lvgl-多页面(screen)设定/切换的更多相关文章

  1. ruby-on-rails - rails : "missing partial" when calling 'render' in RSpec test - 2

    我正在尝试测试是否存在表单。我是Rails新手。我的new.html.erb_spec.rb文件的内容是:require'spec_helper'describe"messages/new.html.erb"doit"shouldrendertheform"dorender'/messages/new.html.erb'reponse.shouldhave_form_putting_to(@message)with_submit_buttonendendView本身,new.html.erb,有代码:当我运行rspec时,它失败了:1)messages/new.html.erbshou

  2. ruby-on-rails - 由于 "wkhtmltopdf",PDFKIT 显然无法正常工作 - 2

    我在从html页面生成PDF时遇到问题。我正在使用PDFkit。在安装它的过程中,我注意到我需要wkhtmltopdf。所以我也安装了它。我做了PDFkit的文档所说的一切......现在我在尝试加载PDF时遇到了这个错误。这里是错误:commandfailed:"/usr/local/bin/wkhtmltopdf""--margin-right""0.75in""--page-size""Letter""--margin-top""0.75in""--margin-bottom""0.75in""--encoding""UTF-8""--margin-left""0.75in""-

  3. ruby-on-rails - 'compass watch' 是如何工作的/它是如何与 rails 一起使用的 - 2

    我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t

  4. ruby-on-rails - 如何从 format.xml 中删除 <hash></hash> - 2

    我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为

  5. ruby - 检查 "command"的输出应该包含 NilClass 的意外崩溃 - 2

    为了将Cucumber用于命令行脚本,我按照提供的说明安装了arubagem。它在我的Gemfile中,我可以验证是否安装了正确的版本并且我已经包含了require'aruba/cucumber'在'features/env.rb'中为了确保它能正常工作,我写了以下场景:@announceScenario:Testingcucumber/arubaGivenablankslateThentheoutputfrom"ls-la"shouldcontain"drw"假设事情应该失败。它确实失败了,但失败的原因是错误的:@announceScenario:Testingcucumber/ar

  6. ruby-on-rails - Rails 3.2.1 中 ActionMailer 中的未定义方法 'default_content_type=' - 2

    我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer

  7. ruby-on-rails - Ruby on Rails with Haml - 如何从 erb 切换 - 2

    我正在从erb文件切换到HAML。我将hamlgem添加到我的系统中。我创建了app/views/layouts/application.html.haml文件。我应该只删除application.html.erb文件吗?此外,仍然有/public/index.html文件被呈现为默认页面。我想创建自己的默认index.html.haml页面。我应该把它放在哪里以及如何使系统呈现该文件而不是默认索引文件?谢谢! 最佳答案 是的,您可以删除任何已转换为HAML的View的ERB版本。至于你的另一个问题,删除public/index/h

  8. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  9. ruby - 在 jRuby 中使用 'fork' 生成进程的替代方案? - 2

    在MRIRuby中我可以这样做:deftransferinternal_server=self.init_serverpid=forkdointernal_server.runend#Maketheserverprocessrunindependently.Process.detach(pid)internal_client=self.init_client#Dootherstuffwithconnectingtointernal_server...internal_client.post('somedata')ensure#KillserverProcess.kill('KILL',

  10. ruby - 主要 :Object when running build from sublime 的未定义方法 `require_relative' - 2

    我已经从我的命令行中获得了一切,所以我可以运行rubymyfile并且它可以正常工作。但是当我尝试从sublime中运行它时,我得到了undefinedmethod`require_relative'formain:Object有人知道我的sublime设置中缺少什么吗?我正在使用OSX并安装了rvm。 最佳答案 或者,您可以只使用“require”,它应该可以正常工作。我认为“require_relative”仅适用于ruby​​1.9+ 关于ruby-主要:Objectwhenrun

随机推荐