《使用wxWidgets进行跨平台程序开发》chap09——布局一个对话框
/////////////////////////////////////////////////////////////////////////////
// Name: personalrecord.h
// Purpose: Dialog to get name, age, sex, and voting preference
// Author: Julian Smart
// Created: 02/28/04 06:52:49
// Copyright: (c) 2004, Julian Smart
// Licence: wxWindows license
///////////////////////////////////////////////////////////////////////////// #ifndef _PERSONALRECORD_H_
#define _PERSONALRECORD_H_ #ifdef __GNUG__
#pragma interface "personalrecord.cpp"
#endif /*!
* Includes
*/ #include "wx/spinctrl.h"
#include "wx/statline.h" /*!
* Control identifiers
*/ /**< 事件标识符 */
enum{
ID_PERSONAL_RECORD = ,
ID_NAME = ,
ID_AGE = ,
ID_SEX = ,
ID_VOTE = ,
ID_RESET =
}; /*!
* PersonalRecordDialog class declaration
*/ /**< 一个简单的对话框类 */
class PersonalRecordDialog: public wxDialog
{ private: DECLARE_CLASS( PersonalRecordDialog ) //提供运行期类型信息 // This class handles events
DECLARE_EVENT_TABLE() public: // Constructors
PersonalRecordDialog(); /**< 一个标准的构造函数 */
PersonalRecordDialog(
wxWindow* parent, //父窗口
wxWindowID id = ID_PERSONAL_RECORD, //指定事件标志
const wxString& caption = wxT("Personal Record"), //标题
const wxPoint& pos = wxDefaultPosition, //默认的位置
const wxSize& size = wxDefaultSize, //默认的大小
long style = wxCAPTION|wxRESIZE_BORDER|wxSYSTEM_MENU //对话框类型:显示标题、可变大小的边框、显示系统菜单
); /**<
依照wxWidgets的惯例,我们同时支持了单步创建和两步窗口的方式,单步创建使用的是一个复杂
的构造函数,而两步创建则使用的是一个简单的额构造函数和一个复杂的Create函数
*/ /// Member initialisation
void Init(); /// Creation
/**< 用于二步初始化的初始化函数 */
bool Create(
wxWindow* parent,
wxWindowID id = ID_PERSONAL_RECORD,
const wxString& caption = wxT("Personal Record"),
const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize,
long style = wxCAPTION|wxRESIZE_BORDER|wxSYSTEM_MENU
); /// Creates the controls and sizers
/**< 组件这个对话框,被Create()函数调用 */
/**< 在CreateControls函数中,我们使用了一个垂直盒子布局控件嵌套了另外一个垂直盒子布局控件
以便使对话框产生边界.一个水平的盒子布局控件用来放置wxSpinCtrl, wxChoice和wxCheckBox,以
及另外一个水平盒子布局控件来放置四个按钮 */
void CreateControls(); /// Sets the validators for the dialog controls
/**< 有一个更容易的方法.wxWidgets支持验证器,所谓验证器是一个把数据变量和对应的控
件联系起来的对象.虽然不总是可以使用,但是只要可以使用,总是可以节省你大量的时间和代码来进
行数据的传输和验证 */
void SetDialogValidators(); /// Sets the help text for the dialog controls
/**< 设置帮助文本 */
void SetDialogHelp(); /// Name accessors
void SetName(const wxString& name) { m_name = name; }
wxString GetName() const { return m_name; } /// Age accessors
void SetAge(int age) { m_age = age; }
int GetAge() const { return m_age; } /// Sex accessors (male = false, female = true)
void SetSex(bool sex) { sex ? m_sex = : m_sex = ; }
bool GetSex() const { return m_sex == ; } /// Does the person vote?
void SetVote(bool vote) { m_vote = vote; }
bool GetVote() const { return m_vote; } //// PersonalRecordDialog event handler declarations
/**< 事件响应函数 */ /// wxEVT_UPDATE_UI event handler for ID_VOTE
void OnVoteUpdate( wxUpdateUIEvent& event ); /// wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_RESET
void OnResetClick( wxCommandEvent& event ); /// wxEVT_COMMAND_BUTTON_CLICKED event handler for wxID_HELP
void OnHelpClick( wxCommandEvent& event ); //// PersonalRecordDialog member variables /// Data members
wxString m_name;
int m_age;
int m_sex;
bool m_vote;
}; #endif // _PERSONALRECORD_H_
/////////////////////////////////////////////////////////////////////////////
// Name: personalrecord.cpp
// Purpose: Dialog to get name, age, sex, and voting preference
// Author: Julian Smart
// Created: 02/28/04 06:52:49
// Copyright: (c) 2004, Julian Smart
// Licence: wxWindows license
///////////////////////////////////////////////////////////////////////////// #ifdef __GNUG__
#pragma implementation "personalrecord.h"
#endif #include "wx/wx.h" #include "wx/valtext.h"
#include "wx/valgen.h"
#include "wx/cshelp.h" #include "personalrecord.h" /*!
* PersonalRecordDialog type definition
*/ IMPLEMENT_CLASS( PersonalRecordDialog, wxDialog ) /*!
* PersonalRecordDialog event table definition
*/ BEGIN_EVENT_TABLE( PersonalRecordDialog, wxDialog )
EVT_UPDATE_UI ( ID_VOTE, PersonalRecordDialog::OnVoteUpdate )
EVT_BUTTON ( ID_RESET, PersonalRecordDialog::OnResetClick )
EVT_BUTTON ( wxID_HELP, PersonalRecordDialog::OnHelpClick )
END_EVENT_TABLE() /*!
* PersonalRecordDialog constructors
*/ PersonalRecordDialog::PersonalRecordDialog()
{
Init();
} PersonalRecordDialog::PersonalRecordDialog( wxWindow* parent,
wxWindowID id,
const wxString& caption,
const wxPoint& pos,
const wxSize& size,
long style )
{
Init(); Create(parent, id, caption, pos, size, style);
} /// Initialisation
void PersonalRecordDialog::Init()
{
m_name = wxEmptyString;
m_age = ;
m_sex = false;
m_vote = false;
} /*!
* PersonalRecord creator
*/ bool PersonalRecordDialog::Create( wxWindow* parent,
wxWindowID id,
const wxString& caption,
const wxPoint& pos,
const wxSize& size,
long style )
{
// We have to set extra styles before creating the
// dialog /**< 在创建对话框之前设置一些属性值 */ /**< wxWS_EX_BLOCK_EVENTS:
wxCommandEvents事件将会在无法在当前事件表中找到匹配的时候在其父窗口中尝试匹配,
设置这个扩展属性可以阻止这个行为。Dialog类型的窗口默认设置了这个类型,
但是如果SetExtraStyle函数被应用程序类调用过的话,默认设置可能被覆盖. */ /**< wxDIALOG_EX_CONTEXTHELP:
在Windows平台上,这个扩展类型使得对话框增加一个查询按钮.如果这个按钮被按下,
对话框将进入一种帮助模式,在这种模式下,无论用户点击哪个子窗口,都将发送一个
wxEVT_HELP事件. 这个扩展类型不可以和wxMAXIMIZE BOX和wxMINIMIZE BOX类型混用 */
SetExtraStyle(wxWS_EX_BLOCK_EVENTS|wxDIALOG_EX_CONTEXTHELP); /**< 调用wxDialog的Create函数初始化 */
if (!wxDialog::Create( parent, id, caption, pos, size, style ))
{
return false;
} /**< 把整个对话框窗口的组件布局好 */
CreateControls(); /**< 设置组件对应的帮助文本提示 */
SetDialogHelp(); /**< 把数据和对应控件联系起来 */
SetDialogValidators(); // This fits the dialog to the minimum size dictated by
// the sizers GetSizer()->Fit(this); // This ensures that the dialog cannot be sized smaller
// than the minimum size GetSizer()->SetSizeHints(this); // Centre the dialog on the parent or (if none) screen Centre(); return true;
} /*!
* Control creation for PersonalRecordDialog
*/ void PersonalRecordDialog::CreateControls()
{
// A top-level sizer
/**< 一个顶层布局控件 */
wxBoxSizer* topSizer = new wxBoxSizer(wxVERTICAL);
/**< 设置为这个对话框的主布局控件 */
this->SetSizer(topSizer); // A second box sizer to give more space around the controls
/**< 第二个顶层布局控件来产生边界 */
wxBoxSizer* boxSizer = new wxBoxSizer(wxVERTICAL);
/**< 缩放因子为0、水平居中、四周都有空白边框、空白边框大小为5 */
topSizer->Add(boxSizer, , wxALIGN_CENTER_HORIZONTAL|wxALL, ); // A friendly message
/**< 一个静态文本控件 */
wxStaticText* descr = new wxStaticText( this, wxID_STATIC,
wxT("Please enter your name, age and sex, and specify whether you wish to\nvote in a general election."), wxDefaultPosition, wxDefaultSize, );
/**< 把这个静态文本控件添加到子布局控件中 */
boxSizer->Add(descr, , wxALIGN_LEFT|wxALL, ); // Spacer
/**< 在子布局控件中添加一段空白:长、宽、缩放因子、水平居中、边界空白5像素 */
boxSizer->Add(, , , wxALIGN_CENTER_HORIZONTAL|wxALL, ); // Label for the name text control
/**< 静态文本:Name */
wxStaticText* nameLabel = new wxStaticText ( this, wxID_STATIC,
wxT("&Name:"), wxDefaultPosition, wxDefaultSize, );
boxSizer->Add(nameLabel, , wxALIGN_LEFT|wxALL, ); //左对齐 // A text control for the user's name
/**< 一个用于输入用户名的文本框 */
wxTextCtrl* nameCtrl = new wxTextCtrl ( this, ID_NAME, wxT("Emma"), wxDefaultPosition, wxDefaultSize, );
boxSizer->Add(nameCtrl, , wxGROW|wxALL, ); //子元素随这布局控件一起改变大小 // A horizontal box sizer to contain age, sex and vote
/**< 一个水平布局控件用来放置年龄性别和是否投票 */
wxBoxSizer* ageSexVoteBox = new wxBoxSizer(wxHORIZONTAL);
boxSizer->Add(ageSexVoteBox, , wxGROW|wxALL, ); //子元素随这布局控件一起改变大小 // Label for the age control
/**< 静态文本:Age */
wxStaticText* ageLabel = new wxStaticText ( this, wxID_STATIC,
wxT("&Age:"), wxDefaultPosition, wxDefaultSize, );
ageSexVoteBox->Add(ageLabel, , wxALIGN_CENTER_VERTICAL|wxALL, ); //垂直对齐 // A spin control for the user's age
/**< 用于输入年龄的控件spin */
wxSpinCtrl* ageSpin = new wxSpinCtrl ( this, ID_AGE,
wxEmptyString, wxDefaultPosition, wxSize(, -),
wxSP_ARROW_KEYS, , , ); //用户可以通过方向键改变相关值、范围0 ~ 120、默认25
ageSexVoteBox->Add(ageSpin, , wxALIGN_CENTER_VERTICAL|wxALL, ); //垂直对齐 // Label for the sex control
/**< 静态文本:Sex */
wxStaticText* sexLabel = new wxStaticText ( this, wxID_STATIC,
wxT("&Sex:"), wxDefaultPosition, wxDefaultSize, );
ageSexVoteBox->Add(sexLabel, , wxALIGN_CENTER_VERTICAL|wxALL, ); //垂直对齐 // Create the sex choice control /*
/**< 性别选择框 */
wxString sexStrings[] = {
wxT("Male"),
wxT("Female")
}; wxChoice* sexChoice = new wxChoice ( this, ID_SEX,
wxDefaultPosition, wxSize(, -), WXSIZEOF(sexStrings),
sexStrings, ); sexChoice->SetStringSelection(wxT("Female")); //设置默认选项
ageSexVoteBox->Add(sexChoice, , wxALIGN_CENTER_VERTICAL|wxALL, ); //垂直对齐 // Add a spacer that stretches to push the Vote control
// to the right
/**< 在子布局中添加一段空白:长、宽、缩放因子1、垂直对齐 */
/**< 增加一个可拉升的空白区域,以便让投票选项出现在右边 */
ageSexVoteBox->Add(, , , wxALIGN_CENTER_VERTICAL|wxALL, ); /**< 添加一个选择框 */
wxCheckBox* voteCheckBox = new wxCheckBox( this, ID_VOTE,
wxT("&Vote"), wxDefaultPosition, wxDefaultSize, );
voteCheckBox ->SetValue(true); //默认为选中
ageSexVoteBox->Add(voteCheckBox, , wxALIGN_CENTER_VERTICAL|wxALL, ); //垂直对齐 // A dividing line before the OK and Cancel buttons
/**< 创建一个静态分割条 */
wxStaticLine* line = new wxStaticLine ( this, wxID_STATIC,
wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
boxSizer->Add(line, , wxGROW|wxALL, ); // A horizontal box sizer to contain Reset, OK, Cancel and Help
/**< 用来放置四个按钮的水平盒子布局控件 */
wxBoxSizer* okCancelBox = new wxBoxSizer(wxHORIZONTAL);
boxSizer->Add(okCancelBox, , wxALIGN_CENTER_HORIZONTAL|wxALL, ); // The Reset button
/**< Reset按钮 */
wxButton* reset = new wxButton( this, ID_RESET, wxT("&Reset"),
wxDefaultPosition, wxDefaultSize, );
okCancelBox->Add(reset, , wxALIGN_CENTER_VERTICAL|wxALL, ); // The OK button
/**< OK按钮 */
wxButton* ok = new wxButton ( this, wxID_OK, wxT("&OK"),
wxDefaultPosition, wxDefaultSize, );
okCancelBox->Add(ok, , wxALIGN_CENTER_VERTICAL|wxALL, ); // The Cancel button
/**< Cancel按钮 */
wxButton* cancel = new wxButton ( this, wxID_CANCEL,
wxT("&Cancel"), wxDefaultPosition, wxDefaultSize, );
okCancelBox->Add(cancel, , wxALIGN_CENTER_VERTICAL|wxALL, ); // The Help button
/**< Help按钮 */
wxButton* help = new wxButton( this, wxID_HELP,
wxT("&Help"), wxDefaultPosition, wxDefaultSize, );
okCancelBox->Add(help, , wxALIGN_CENTER_VERTICAL|wxALL, );
} // Set the validators for the dialog controls
/**< 把数据和对应控件联系起来 */
void PersonalRecordDialog::SetDialogValidators()
{
/**< wxGenericValidator是一个很简单的验证器,它只负责传输数据,不对数据进行校验,
也正因为如此,它支持更多的基本控件 */ /**< 别的验证器则象wxTextValidator一样,提供了各种的校验方法,比如wxTextValidator
就可以阻止那些不合法的按键事件传入文本框控件.在这个例子中,我们只是使用了标准校验类型
wxFILTER ALPHA,但是通过验证器的SetIncludes和SetExcludes函数,我们还可以指定具体哪些字符
是允许的哪些是不允许的. */ FindWindow(ID_NAME)->SetValidator(wxTextValidator(wxFILTER_ALPHA, & m_name)); FindWindow(ID_AGE)->SetValidator(wxGenericValidator(& m_age)); FindWindow(ID_SEX)->SetValidator(wxGenericValidator(& m_sex)); FindWindow(ID_VOTE)->SetValidator(wxGenericValidator(& m_vote));
} // Sets the help text for the dialog controls
/**< 设置对话框的帮助文本 */
void PersonalRecordDialog::SetDialogHelp()
{
wxString nameHelp = wxT("Enter your full name.");
wxString ageHelp = wxT("Specify your age.");
wxString sexHelp = wxT("Specify your gender, male or female.");
wxString voteHelp = wxT("Check this if you wish to vote."); FindWindow(ID_NAME)->SetHelpText(nameHelp); //上下文敏感帮助
FindWindow(ID_NAME)->SetToolTip(nameHelp); //工具提示帮助 FindWindow(ID_AGE)->SetHelpText(ageHelp);
FindWindow(ID_AGE)->SetToolTip(ageHelp); FindWindow(ID_SEX)->SetHelpText(sexHelp);
FindWindow(ID_SEX)->SetToolTip(sexHelp); FindWindow(ID_VOTE)->SetHelpText(voteHelp);
FindWindow(ID_VOTE)->SetToolTip(voteHelp); //wxHelpProvider::Set(new wxSimpleHelpProvider);
} /*
* wxEVT_UPDATE_UI event handler for ID_CHECKBOX
*/ void PersonalRecordDialog::OnVoteUpdate( wxUpdateUIEvent& event )
{
wxSpinCtrl* ageCtrl = (wxSpinCtrl*) FindWindow(ID_AGE); /**< 要注意在代码中我们不能直接判断m age成员,因为
这个成员只有在用户点击了OK按钮以后才会将控件的数据传递过来 */
if (ageCtrl->GetValue() < )
{
event.Enable(false); //不能选中
event.Check(false); //选框灰色
}
else
event.Enable(true);
} /*!
* wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_RESET
*/
/**< 处理reset按钮事件 */
void PersonalRecordDialog::OnResetClick( wxCommandEvent& event )
{
Init(); //初始化
TransferDataToWindow(); //将数据传输到控件
} /*!
* wxEVT_COMMAND_BUTTON_CLICKED event handler for wxID_HELP
*/
/**< 处理help按钮事件 */
void PersonalRecordDialog::OnHelpClick( wxCommandEvent& event )
{
// Normally we would wish to display proper online help.
// For this example, we're just using a message box.
/*
wxGetApp().GetHelpController().DisplaySection(wxT("Personal record dialog"));
*/ wxString helpText =
wxT("Please enter your full name, age and gender.\n")
wxT("Also indicate your willingness to vote in general elections.\n\n")
wxT("No non-alphabetical characters are allowed in the name field.\n")
wxT("Try to be honest about your age."); wxMessageBox(helpText,
wxT("Personal Record Dialog Help"),
wxOK|wxICON_INFORMATION, this);
}
// Name: demo.cpp
// Purpose: Demo for PersonalRecordDialog
// Author: Julian Smart
// License: wxWindows License #include "wx/wx.h"
#include "personalrecord.h" // Declare the application class
class MyApp : public wxApp
{
public:
// Called on application startup
virtual bool OnInit();
}; // Declare our main frame class
class MyFrame : public wxFrame
{
public:
// Constructor
MyFrame(const wxString & title); // Event handlers
void OnQuit (wxCommandEvent & event);
void OnAbout (wxCommandEvent & event);
void OnShowDialog (wxCommandEvent & event); enum{
ID_SHOW_DIALOG
}; private:
// This class handles events
DECLARE_EVENT_TABLE()
}; // Implements MyApp & GetApp()
DECLARE_APP(MyApp) // Give wxWidgets the means to create a MyApp object
IMPLEMENT_APP(MyApp) // Initialize the application
bool MyApp::OnInit()
{
// Create the main application window
MyFrame * frame = new MyFrame(wxT("PersonalRecordDialog Demo")); // Show it
frame->Show(true); // Start the event loop
return true;
} // Event table for MyFrame
BEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_MENU(wxID_ABOUT, MyFrame::OnAbout)
EVT_MENU(wxID_EXIT, MyFrame::OnQuit)
EVT_MENU(ID_SHOW_DIALOG, MyFrame::OnShowDialog)
END_EVENT_TABLE() void MyFrame::OnAbout(wxCommandEvent & event)
{
wxString msg;
msg.Printf(wxT("PersonalRecordDialog example, built with wxWidgets %s"),
wxVERSION_STRING); wxMessageBox(msg, wxT("About this program"),
wxOK | wxICON_INFORMATION, this);
} void MyFrame::OnQuit(wxCommandEvent & event)
{
// Destroy the frame
Close(true);
} void MyFrame::OnShowDialog(wxCommandEvent & event)
{
PersonalRecordDialog dialog(this, wxID_ANY, wxT("Personal Record"),
wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE);
dialog.ShowModal();
} #include "mondrian.xpm" MyFrame::MyFrame(const wxString & title)
: wxFrame(NULL, wxID_ANY, title)
{
// Set the frame icon
SetIcon(wxIcon(mondrian_xpm)); // Create a menu bar
wxMenu * fileMenu = new wxMenu; // The "About" item should be in the help menu
wxMenu * helpMenu = new wxMenu;
helpMenu->Append(wxID_ABOUT, wxT("&About...\tF1"),
wxT("Show about dialog")); fileMenu->Append(ID_SHOW_DIALOG, wxT("&Show Personal Record Dialog..."),
wxT("Show Personal Record Dialog"));
fileMenu->Append(wxID_EXIT, wxT("E&xit\tAlt-X"),
wxT("Quit this program")); // Now append the freshly created menu to the menu bar...
wxMenuBar *menuBar = new wxMenuBar();
menuBar->Append(fileMenu, wxT("&File"));
menuBar->Append(helpMenu, wxT("&Help")); // ... and attach this menu bar to the frame
SetMenuBar(menuBar); CreateStatusBar();
SetStatusText(wxT("welcome to wxWidgets!"), );
}
《使用wxWidgets进行跨平台程序开发》chap09——布局一个对话框的更多相关文章
- 《使用wxWidgets进行跨平台程序开发》chap02——一个简单的应用程序
// Name: minimal.cpp // Purpose: Minimal wxWidgets sample // Author: Julian Smart #include "wx/ ...
- 在C#/.NET应用程序开发中创建一个基于Topshelf的应用程序守护进程(服务)
本文首发于:码友网--一个专注.NET/.NET Core开发的编程爱好者社区. 文章目录 C#/.NET基于Topshelf创建Windows服务的系列文章目录: C#/.NET基于Topshelf ...
- Win32 程序开发:创建一个应用程序窗口
一.创建一个应用程序窗口 代码如下: // 头文件 #include <windows.h> // 全局变量 WCHAR g_lpszClassName[] = L"CLASSN ...
- 微信小程序开发03-这是一个组件
编写组件 基本结构 接上文:微信小程序开发02-小程序基本介绍 我们今天先来实现这个弹出层: 之前这个组件是一个容器类组件,弹出层可设置载入的html结构,然后再设置各种事件即可,这种组件有一个特点: ...
- Win32 程序开发入门:一个最简单的Win32程序
一.什么是 Win32 Win32 是指 Microsoft Windows 操作系统的 32 位环境,与 Win64 都为 Windows 常见环境. 这里再介绍下 Win32 Applicatio ...
- 微信小程序开发:Flex布局
微信小程序页面布局方式采用的是Flex布局.Flex布局,是W3c在2009年提出的一种新的方案,可以简便,完整,响应式的实现各种页面布局.Flex布局提供了元素在容器中的对齐,方向以及顺序,甚至他们 ...
- 微信小程序开发——打开另一个小程序
微信小程序打开另一个小程序,有两种方法:1.超链接:2.点击按钮. 全局配置: 跳转到其他小程序,需要在当前小程序全局配置中配置需要跳转的小程序列表,代码如下: App.json { ... &quo ...
- win32界面程序开发,自制一个会自动销毁的提示框
思路:创建线程里面启动窗口,设置定时器关闭该窗口. 创建窗口几个步骤和一般窗口无异,注册.然后createwindow,之后showwinodw,然后消息循环. 在createwindow之后,获取到 ...
- mpvue小程序开发之 实现一个弹幕评论
先上图 就是一个简单的弹幕发送功能 弹幕区的页面: <div class="content" v-show="doommData.length"> ...
随机推荐
- URL重写 UrlRewrite
为什么要URL重写? 1.有利于SEO,带参数的URL权重较低: 2.地址看起来更正规,推广uid 伪静态:看起来像普通页面,而非动态生成的页面. 原理:在Global.asax的Applicatio ...
- 切割TOMCAT日志
tomcat的catalina.out日志如果不做操作的话,日志就会日积月累的不断增加.我刚入职的时候发现某台服务器的硬盘报警,排查之后我慌了,一个tomcat的日志居然有100G,这怎么可以,在网上 ...
- SVN资料库转移-----dump和load
最近由于大批量的更换服务器,所以之前布署的SVN服务器需要重新布署,需要把原来的资源库转移到新服务器上,并且使管理的项目版本一致,在网上查了一下SVN版本库迁移,但看了一上google出来的也很少,所 ...
- git 彩色显示当前branch
环境: fedora 20 $ curl https://raw.githubusercontent.com/git/git/master/contrib/completion/git-prompt. ...
- eval(phpcode) 字符当代码执行
eval(phpcode)eval() 函数把字符串按照 PHP 代码来计算.相当于在字符串两边分别加上PHP语 法标签 该字符串必须是合法的 PHP 代码,且必须以分号结尾. 如果没有在代码字符串中 ...
- float right 换行bug
Bug产生原因:块里面有换行的元素. CSS: .left{float: left;width: 100px;background: #fff000;} .right{float: right;wid ...
- PHP优化小结
1.echo 比 print 快,并且使用echo的多重参数(指用逗号而不是句点)代替字符串连接,比如echo $str1,$str2.如果使用echo $str1.$str2 就会需要 PHP 引擎 ...
- setTimeout和setInterval的深入理解
以前写的setTimeout和setInterval的文章有些不足之处,今天抽时间整理了一下,要想真正理解还得从javascript的单线程机制说起 大概半年前发表过一篇关于setTimeout和se ...
- 限制apache错误日志大小
①配置错误日志 在http.conf配置: ErrorLog "| /opt/lampp/bin/rotatelogs /opt/lampp/logs/%Y_%m_%d_error_log ...
- 重构技巧 引入Null对象
描述:有两个类,学生类和导师类,学生的导师类可能不存在,因此在获取学生导师名字等信息时都要先判断导师名字是否为空.重构后通过一个空导师类来处理导师为空的相应逻辑. Before # introduce ...