原文地址:http://blog.163.com/net_worm/blog/static/127702419201001003326522/

在简单的QT程序的第二行,声明了一个QPushButton的对象。先简单看看其初始化过程。

QPushButton的类继承关系为:

1 QPushButton :public QAbstractButton :pubic QWidget :public QObject, public QPaintDevice

QPushButton的构造:

1 QPushButton::QPushButton(const QString &text, QWidget *parent)
2 : QAbstractButton(*new QPushButtonPrivate, parent)
3 {
4 Q_D(QPushButton); // 声明并获得QPushButtonPrivate函数指针d
5 setText(text); // 设置按钮的名字
6 d->init(); // 调用QPushButtonPrivate::init(),其实只是重新设定排布间隔
7 }

新生成的QPushButtonPrivate对象传递给QAbstractButton之后,发生了什么事呢?

1 QAbstractButton::QAbstractButton(QAbstractButtonPrivate &dd, QWidget *parent)
2 : QWidget(dd, parent, 0)
3 {
4 Q_D(QAbstractButton); // 声明并获得QAbstractButtonPrivate函数指针d
5 d->init(); // 调用QAbstractButtonPrivate::init()
6 }

QAbstractButtonPrivate::init()做了什么呢?其实只是调用了QPushButton的几个设定函数。

继续看QWidget的初始化过程。

1 QWidget::QWidget(QWidgetPrivate &dd, QWidget* parent, Qt::WindowFlags f)
2 : QObject(dd, 0), QPaintDevice()
3 {
4 d_func()->init(parent, f);
5 }

其中d_func()是宏定义Q_DECLARE_PRIVATE(QWidget)中定义的,获取QWidgetPrivate指针的函数。有点奇怪的是,这里怎么没有用Q_D宏定义,与之前的风格有点不同。

QWidgetPrivate::init()里做了什么动作呢?(关键语句用颜色标记)

 1 void QWidgetPrivate::init(QWidget *parentWidget, Qt::WindowFlags f)
2 {
3 Q_Q(QWidget);
4 if (qApp->type() == QApplication::Tty)
5 qFatal("QWidget: Cannot create a QWidget when no GUI is being used");
6
7 Q_ASSERT(uncreatedWidgets);
8 uncreatedWidgets->insert(q);
9
10 QWidget *desktopWidget = 0;
11 if (parentWidget && parentWidget->windowType() == Qt::Desktop) {
12 desktopWidget = parentWidget;
13 parentWidget = 0;
14 }
15
16 q->data = &data;
17
18 if (!q->parent()) {
19 Q_ASSERT_X(q->thread() == qApp->thread(), "QWidget",
20 "Widgets must be created in the GUI thread.");
21 }
22
23 data.fstrut_dirty = true;
24
25 data.winid = 0;
26 data.widget_attributes = 0;
27 data.window_flags = f;
28 data.window_state = 0;
29 data.focus_policy = 0;
30 data.context_menu_policy = Qt::DefaultContextMenu;
31 data.window_modality = Qt::NonModal;
32
33 data.sizehint_forced = 0;
34 data.is_closing = 0;
35 data.in_show = 0;
36 data.in_set_window_state = 0;
37 data.in_destructor = false;
38
39 // Widgets with Qt::MSWindowsOwnDC (typically QGLWidget) must have a window handle.
40 if (f & Qt::MSWindowsOwnDC)
41 q->setAttribute(Qt::WA_NativeWindow);
42
43 q->setAttribute(Qt::WA_QuitOnClose); // might be cleared in adjustQuitOnCloseAttribute()
44 adjustQuitOnCloseAttribute();
45
46 q->setAttribute(Qt::WA_WState_Hidden);
47
48 //give potential windows a bigger "pre-initial" size; create_sys() will give them a new size later
49 data.crect = parentWidget ? QRect(0,0,100,30) : QRect(0,0,640,480);
50
51 focus_next = focus_prev = q;
52
53 if ((f & Qt::WindowType_Mask) == Qt::Desktop)
54 q->create(); // 调用了QWidget::create()
55 else if (parentWidget)
56 q->setParent(parentWidget, data.window_flags);
57 else {
58 adjustFlags(data.window_flags, q);
59 resolveLayoutDirection();
60 // opaque system background?
61 const QBrush &background = q->palette().brush(QPalette::Window);
62 setOpaque(q->isWindow() && background.style() != Qt::NoBrush && background.isOpaque());
63 }
64 data.fnt = QFont(data.fnt, q);
65
66 q->setAttribute(Qt::WA_PendingMoveEvent);
67 q->setAttribute(Qt::WA_PendingResizeEvent);
68
69 if (++QWidgetPrivate::instanceCounter > QWidgetPrivate::maxInstances)
70 QWidgetPrivate::maxInstances = QWidgetPrivate::instanceCounter;
71
72 if (QApplicationPrivate::app_compile_version < 0x040200
73 || QApplicationPrivate::testAttribute(Qt::AA_ImmediateWidgetCreation))
74 q->create();
75
76 // 下面的三行,产生并发送了Create事件
77 QEvent e(QEvent::Create);
78 QApplication::sendEvent(q, &e);
79 QApplication::postEvent(q, new QEvent(QEvent::PolishRequest));
80
81 extraPaintEngine = 0;
82 }

看看QWidget::create()的实现:

 1 void QWidget::create(WId window, bool initializeWindow, bool destroyOldWindow)
2 {
3 Q_D(QWidget);
4 if (testAttribute(Qt::WA_WState_Created) && window == 0 && internalWinId())
5 return;
6
7 if (d->data.in_destructor)
8 return;
9
10 Qt::WindowType type = windowType();
11 Qt::WindowFlags &flags = data->window_flags;
12
13 if ((type == Qt::Widget || type == Qt::SubWindow) && !parentWidget()) {
14 type = Qt::Window;
15 flags |= Qt::Window;
16 }
17
18 if (QWidget *parent = parentWidget()) {
19 if (type & Qt::Window) {
20 if (!parent->testAttribute(Qt::WA_WState_Created))
21 parent->createWinId();
22 } else if (testAttribute(Qt::WA_NativeWindow) && !parent->internalWinId()
23 && !testAttribute(Qt::WA_DontCreateNativeAncestors)) {
24 // We're about to create a native child widget that doesn't have a native parent;
25 // enforce a native handle for the parent unless the Qt::WA_DontCreateNativeAncestors
26 // attribute is set.
27 d->createWinId(window);
28 // Nothing more to do.
29 Q_ASSERT(testAttribute(Qt::WA_WState_Created));
30 Q_ASSERT(internalWinId());
31 return;
32 }
33 }
34
35 static int paintOnScreenEnv = -1;
36 if (paintOnScreenEnv == -1)
37 paintOnScreenEnv = qgetenv("QT_ONSCREEN_PAINT").toInt() > 0 ? 1 : 0;
38 if (paintOnScreenEnv == 1)
39 setAttribute(Qt::WA_PaintOnScreen);
40
41 if (QApplicationPrivate::testAttribute(Qt::AA_NativeWindows))
42 setAttribute(Qt::WA_NativeWindow);
43
44 #ifdef ALIEN_DEBUG
45 qDebug() << "QWidget::create:" << this << "parent:" << parentWidget()
46 << "Alien?" << !testAttribute(Qt::WA_NativeWindow);
47 #endif
48
49 // Unregister the dropsite (if already registered) before we
50 // re-create the widget with a native window.
51 if (testAttribute(Qt::WA_WState_Created) && !internalWinId() && testAttribute(Qt::WA_NativeWindow)
52 && d->extra && d->extra->dropTarget) {
53 d->registerDropSite(false);
54 }
55
56 d->updateIsOpaque();
57
58 setAttribute(Qt::WA_WState_Created); // set created flag
59 d->create_sys(window, initializeWindow, destroyOldWindow);
60
61 // a real toplevel window needs a backing store
62 if (isWindow()) {
63 delete d->topData()->backingStore;
64 // QWidgetBackingStore will check this variable, hence it must be 0
65 d->topData()->backingStore = 0;
66 if (hasBackingStoreSupport())
67 d->topData()->backingStore = new QWidgetBackingStore(this);
68 }
69
70 d->setModal_sys();
71
72 if (!isWindow() && parentWidget() && parentWidget()->testAttribute(Qt::WA_DropSiteRegistered))
73 setAttribute(Qt::WA_DropSiteRegistered, true);
74
75 // need to force the resting of the icon after changing parents
76 if (testAttribute(Qt::WA_SetWindowIcon))
77 d->setWindowIcon_sys(true);
78 if (isWindow() && !d->topData()->iconText.isEmpty())
79 d->setWindowIconText_helper(d->topData()->iconText);
80 if (windowType() != Qt::Desktop) {
81 d->updateSystemBackground();
82
83 if (isWindow() && !testAttribute(Qt::WA_SetWindowIcon))
84 d->setWindowIcon_sys();
85 }
86 }

这里QWidgetPrivate::create_sys()定义在QWidget_win.cpp里。

  1 void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyOldWindow)
2 {
3 Q_Q(QWidget);
4 static int sw = -1, sh = -1;
5
6 Qt::WindowType type = q->windowType();
7 Qt::WindowFlags flags = data.window_flags;
8
9 bool topLevel = (flags & Qt::Window);
10 bool popup = (type == Qt::Popup);
11 bool dialog = (type == Qt::Dialog
12 || type == Qt::Sheet
13 || (flags & Qt::MSWindowsFixedSizeDialogHint));
14 bool desktop = (type == Qt::Desktop);
15 bool tool = (type == Qt::Tool || type == Qt::Drawer);
16
17 HINSTANCE appinst = qWinAppInst();
18 HWND parentw, destroyw = 0;
19 WId id;
20
21 QString windowClassName = qt_reg_winclass(q);
22
23 if (!window) // always initialize
24 initializeWindow = true;
25
26 if (popup)
27 flags |= Qt::WindowStaysOnTopHint; // a popup stays on top
28
29 if (sw < 0) { // get the (primary) screen size
30 sw = GetSystemMetrics(SM_CXSCREEN);
31 sh = GetSystemMetrics(SM_CYSCREEN);
32 }
33
34 if (desktop && !q->testAttribute(Qt::WA_DontShowOnScreen)) { // desktop widget
35 popup = false; // force this flags off
36 if (QSysInfo::WindowsVersion != QSysInfo::WV_NT && QSysInfo::WindowsVersion != QSysInfo::WV_95)
37 data.crect.setRect(GetSystemMetrics(76 /* SM_XVIRTUALSCREEN */), GetSystemMetrics(77 /* SM_YVIRTUALSCREEN */),
38 GetSystemMetrics(78 /* SM_CXVIRTUALSCREEN */), GetSystemMetrics(79 /* SM_CYVIRTUALSCREEN */));
39 else
40 data.crect.setRect(0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
41 }
42
43 parentw = q->parentWidget() ? q->parentWidget()->effectiveWinId() : 0;
44
45 #ifdef UNICODE
46 QString title;
47 const TCHAR *ttitle = 0;
48 #endif
49 QByteArray title95;
50 int style = WS_CHILD;
51 int exsty = 0;
52
53 if (window) {
54 style = GetWindowLongA(window, GWL_STYLE);
55 if (!style)
56 qErrnoWarning("QWidget::create: GetWindowLong failed");
57 topLevel = false; // #### needed for some IE plugins??
58 } else if (popup || (type == Qt::ToolTip) || (type == Qt::SplashScreen)) {
59 style = WS_POPUP;
60 } else if (topLevel && !desktop) {
61 if (flags & Qt::FramelessWindowHint)
62 style = WS_POPUP; // no border
63 else if (flags & Qt::WindowTitleHint)
64 style = WS_OVERLAPPED;
65 else
66 style = 0;
67 }
68 if (!desktop) {
69 // if (!testAttribute(Qt::WA_PaintUnclipped))
70 // ### Commented out for now as it causes some problems, but
71 // this should be correct anyway, so dig some more into this
72 #ifndef Q_FLATTEN_EXPOSE
73 style |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN ;
74 #endif
75 if (topLevel) {
76 if ((type == Qt::Window || dialog || tool)) {
77 if (!(flags & Qt::FramelessWindowHint)) {
78 if (!(flags & Qt::MSWindowsFixedSizeDialogHint)) {
79 style |= WS_THICKFRAME;
80 if(!(flags &
81 ( Qt::WindowSystemMenuHint
82 | Qt::WindowTitleHint
83 | Qt::WindowMinMaxButtonsHint
84 | Qt::WindowCloseButtonHint
85 | Qt::WindowContextHelpButtonHint)))
86 style |= WS_POPUP;
87 } else {
88 style |= WS_POPUP | WS_DLGFRAME;
89 }
90 }
91 if (flags & Qt::WindowTitleHint)
92 style |= WS_CAPTION;
93 if (flags & Qt::WindowSystemMenuHint)
94 style |= WS_SYSMENU;
95 if (flags & Qt::WindowMinimizeButtonHint)
96 style |= WS_MINIMIZEBOX;
97 if (shouldShowMaximizeButton())
98 style |= WS_MAXIMIZEBOX;
99 if (tool)
100 exsty |= WS_EX_TOOLWINDOW;
101 if (flags & Qt::WindowContextHelpButtonHint)
102 exsty |= WS_EX_CONTEXTHELP;
103 } else {
104 exsty |= WS_EX_TOOLWINDOW;
105 }
106 }
107 }
108
109 if (flags & Qt::WindowTitleHint) {
110 QT_WA({
111 title = q->isWindow() ? qAppName() : q->objectName();
112 ttitle = (TCHAR*)title.utf16();
113 } , {
114 title95 = q->isWindow() ? qAppName().toLocal8Bit() : q->objectName().toLatin1();
115 });
116 }
117
118 // The Qt::WA_WState_Created flag is checked by translateConfigEvent() in
119 // qapplication_win.cpp. We switch it off temporarily to avoid move
120 // and resize events during creationt
121 q->setAttribute(Qt::WA_WState_Created, false);
122
123 if (window) { // override the old window
124 if (destroyOldWindow)
125 destroyw = data.winid;
126 id = window;
127 setWinId(window);
128 LONG res = SetWindowLongA(window, GWL_STYLE, style);
129 if (!res)
130 qErrnoWarning("QWidget::create: Failed to set window style");
131 #ifdef _WIN64
132 res = SetWindowLongPtrA( window, GWLP_WNDPROC, (LONG_PTR)QtWndProc );
133 #else
134 res = SetWindowLongA( window, GWL_WNDPROC, (LONG)QtWndProc );
135 #endif
136 if (!res)
137 qErrnoWarning("QWidget::create: Failed to set window procedure");
138 } else if (desktop) { // desktop widget
139 id = GetDesktopWindow();
140 // QWidget *otherDesktop = QWidget::find(id); // is there another desktop?
141 // if (otherDesktop && otherDesktop->testWFlags(Qt::WPaintDesktop)) {
142 // otherDesktop->d_func()->setWinId(0); // remove id from widget mapper
143 // d->setWinId(id); // make sure otherDesktop is
144 // otherDesktop->d_func()->setWinId(id); // found first
145 // } else {
146 setWinId(id);
147 // }
148 } else if (topLevel) { // create top-level widget
149 if (popup)
150 parentw = 0;
151
152 const bool wasMoved = q->testAttribute(Qt::WA_Moved);
153 int x = wasMoved ? data.crect.left() : CW_USEDEFAULT;
154 int y = wasMoved ? data.crect.top() : CW_USEDEFAULT;
155 int w = CW_USEDEFAULT;
156 int h = CW_USEDEFAULT;
157
158 // Adjust for framestrut when needed
159 RECT rect = {0,0,0,0};
160 bool isVisibleOnScreen = !q->testAttribute(Qt::WA_DontShowOnScreen);
161 if (isVisibleOnScreen && AdjustWindowRectEx(&rect, style & ~WS_OVERLAPPED, FALSE, exsty)) {
162 QTLWExtra *td = maybeTopData();
163 if (wasMoved && (td && !td->posFromMove)) {
164 x = data.crect.x() + rect.left;
165 y = data.crect.y() + rect.top;
166 }
167
168 if (q->testAttribute(Qt::WA_Resized)) {
169 w = data.crect.width() + (rect.right - rect.left);
170 h = data.crect.height() + (rect.bottom - rect.top);
171 }
172 }
173 //update position & initial size of POPUP window
174 if (isVisibleOnScreen && topLevel && initializeWindow && (style & WS_POPUP)) {
175 if (!q->testAttribute(Qt::WA_Resized)) {
176 w = sw/2;
177 h = 4*sh/10;
178 }
179 if (!wasMoved) {
180 x = sw/2 - w/2;
181 y = sh/2 - h/2;
182 }
183 }
184
185 QT_WA({
186 const TCHAR *cname = (TCHAR*)windowClassName.utf16();
187 id = CreateWindowEx(exsty, cname, ttitle, style,
188 x, y, w, h,
189 parentw, 0, appinst, 0);
190 } , {
191 id = CreateWindowExA(exsty, windowClassName.toLatin1(), title95, style,
192 x, y, w, h,
193 parentw, 0, appinst, 0);
194 });
195 if (!id)
196 qErrnoWarning("QWidget::create: Failed to create window");
197 setWinId(id);
198 if ((flags & Qt::WindowStaysOnTopHint) || (type == Qt::ToolTip)) {
199 SetWindowPos(id, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
200 if (flags & Qt::WindowStaysOnBottomHint)
201 qWarning() << "QWidget: Incompatible window flags: the window can't be on top and on bottom at the same time";
202 } else if (flags & Qt::WindowStaysOnBottomHint)
203 SetWindowPos(id, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
204 winUpdateIsOpaque();
205 } else if (q->testAttribute(Qt::WA_NativeWindow) || paintOnScreen()) { // create child widget
206 QT_WA({
207 const TCHAR *cname = (TCHAR*)windowClassName.utf16();
208 id = CreateWindowEx(exsty, cname, ttitle, style,
209 data.crect.left(), data.crect.top(), data.crect.width(), data.crect.height(),
210 parentw, NULL, appinst, NULL);
211 } , {
212 id = CreateWindowExA(exsty, windowClassName.toLatin1(), title95, style,
213 data.crect.left(), data.crect.top(), data.crect.width(), data.crect.height(),
214 parentw, NULL, appinst, NULL);
215 });
216 if (!id)
217 qErrnoWarning("QWidget::create: Failed to create window");
218 SetWindowPos(id, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
219 setWinId(id);
220 }
221
222 if (desktop) {
223 q->setAttribute(Qt::WA_WState_Visible);
224 } else if (topLevel && !q->testAttribute(Qt::WA_DontShowOnScreen)) {
225 RECT cr;
226 GetClientRect(id, &cr);
227 // one cannot trust cr.left and cr.top, use a correction POINT instead
228 POINT pt;
229 pt.x = 0;
230 pt.y = 0;
231 ClientToScreen(id, &pt);
232
233 if (data.crect.width() == 0 || data.crect.height() == 0) {
234 data.crect = QRect(pt.x, pt.y, data.crect.width(), data.crect.height());
235 } else {
236 data.crect = QRect(QPoint(pt.x, pt.y),
237 QPoint(pt.x + cr.right - 1, pt.y + cr.bottom - 1));
238 }
239
240 if (data.fstrut_dirty) {
241 // be nice to activeqt
242 updateFrameStrut();
243 }
244 }
245
246 q->setAttribute(Qt::WA_WState_Created); // accept move/resize events
247 hd = 0; // no display context
248
249 if (window) { // got window from outside
250 if (IsWindowVisible(window))
251 q->setAttribute(Qt::WA_WState_Visible);
252 else
253 q->setAttribute(Qt::WA_WState_Visible, false);
254 }
255
256 if (extra && !extra->mask.isEmpty())
257 setMask_sys(extra->mask);
258
259 #if defined(QT_NON_COMMERCIAL)
260 QT_NC_WIDGET_CREATE
261 #endif
262
263 if (q->hasFocus() && q->testAttribute(Qt::WA_InputMethodEnabled))
264 q->inputContext()->setFocusWidget(q);
265
266 if (destroyw) {
267 DestroyWindow(destroyw);
268 }
269
270 if (q != qt_tablet_widget && QWidgetPrivate::mapper)
271 qt_tablet_init();
272
273 if (q->testAttribute(Qt::WA_DropSiteRegistered))
274 registerDropSite(true);
275
276 if (maybeTopData() && maybeTopData()->opacity != 255)
277 q->setWindowOpacity(maybeTopData()->opacity/255.);
278
279 if (topLevel && (data.crect.width() == 0 || data.crect.height() == 0)) {
280 q->setAttribute(Qt::WA_OutsideWSRange, true);
281 }
282
283 if (!topLevel && q->testAttribute(Qt::WA_NativeWindow) && q->testAttribute(Qt::WA_Mapped)) {
284 Q_ASSERT(q->internalWinId());
285 ShowWindow(q->internalWinId(), SW_SHOW);
286 }
287 }

这里调用了qt_reg_winclass()(在QApplication_win.cpp里定义),查看其代码就是RegisterWindows,把window窗口的消息处理设定为:QtWndProc。QObject的初始化没有什么新意,参看QApplication得初始化。

到目前为止的初始化分析,为下一步我们分析Windows消息传递,也就是QT的事件机制打下了基础。

转自:http://www.cnblogs.com/lfsblack/p/5279016.html

2、QT分析之QPushButton的初始化的更多相关文章

  1. QT分析之QPushButton的初始化

    原文地址:http://blog.163.com/net_worm/blog/static/127702419201001003326522/ 在简单的QT程序的第二行,声明了一个QPushButto ...

  2. 1、QT分析之QApplication的初始化

    原文地址:http://blog.163.com/net_worm/blog/static/1277024192010097430321/ 在开始分析之前交代一下,一是分析的QT在Window平台实现 ...

  3. QT分析之QApplication的初始化

    原文地址:http://blog.163.com/net_worm/blog/static/1277024192010097430321/ 在开始分析之前交代一下,一是分析的QT在Window平台实现 ...

  4. 3、QT分析之消息事件机制

    原文地址:http://blog.163.com/net_worm/blog/static/127702419201001432028526/ 上回我们分析到QPushButton的初始化,知道了Wi ...

  5. QT分析之消息事件机制

    原文地址:http://blog.163.com/net_worm/blog/static/127702419201001432028526/ 上回我们分析到QPushButton的初始化,知道了Wi ...

  6. 10、QT分析之WebKit

    该文章整理自 网易博客 http://blog.163.com/net_worm/blog/static/12770241920101831312381/ 转载请注明出处 WebKit是QT4新整合的 ...

  7. 5、QT分析之网络编程

    原文地址:http://blog.163.com/net_worm/blog/static/127702419201002842553382/ 首先对Windows下的网络编程总结一下: 如果是服务器 ...

  8. QT分析之WebKit

    该文章整理自 网易博客 http://blog.163.com/net_worm/blog/static/12770241920101831312381/ 转载请注明出处 WebKit是QT4新整合的 ...

  9. QT分析之网络编程

    原文地址:http://blog.163.com/net_worm/blog/static/127702419201002842553382/ 首先对Windows下的网络编程总结一下: 如果是服务器 ...

随机推荐

  1. remoting生命周期

    https://www.cnblogs.com/luomingui/archive/2011/07/09/2101779.html

  2. [Windows Azure] How to use the Queue Storage Service

    How to use the Queue Storage Service version 1.7 version 2.0 This guide will show you how to perform ...

  3. javascript基础拾遗(十二)

    1.javascript的单线程特性 在javascript中,所有的代码都是单线程的 因此所有的网络操作,浏览器事件,都必须是异步执行的,异步执行的逻辑是回调. function callback( ...

  4. python(42):进制转换

    十六进制 到 十进制 使用 int() 函数 ,第一个参数是字符串 '0Xff' ,第二个参数是说明,这个字符串是几进制的数.  转化的结果是一个十进制数. >>> int('0xf ...

  5. (转)go语言nsq源码解读二 nsqlookupd、nsqd与nsqadmin

    转自:http://www.baiyuxiong.com/?p=886 ---------------------------------------------------------------- ...

  6. 玩转Bootstrap(JS插件篇)-第1章 模态弹出框 :1-1导入JavaScript插件

    导入JavaScript插件 Bootstrap除了包含丰富的Web组件之外,如前面介绍的下拉菜单.按钮组.导航.分页等.他还包括一些JavaScript的插件. Bootstrap的JavaScri ...

  7. Path-to-PegExp的使用

    下载: npm install path-to-regexp --save 引入: var pathToRegexp = require('path-to-regexp') 或者 import pat ...

  8. openfire ping的smack解决方案(维持在线状态)

    连接中关联如下: // iq提供者 roviderManager.getInstance().addIQProvider("ping", "urn:xmpp:ping&q ...

  9. 【linux】dpkg info修复及dpkg: warning: files list file for package

    mv /var/lib/dpkg/info /var/lib/dpkg/info.bak //现将info文件夹更名 sudo mkdir /var/lib/dpkg/info //再新建一个新的in ...

  10. Python nose单元测试框架的安装与使用

    [本文出自天外归云的博客园] 安装(Python2下安装) pip install nose 原理与命名规则 Nose会自动查找源文件.目录或者包中的测试用例,符合正则表达式(?:^|[\b_\.%s ...