NSIS 之 NsDialogs 常见问题解答

如何启用/禁用控件

使用标准 NSIS EnableWindow 命令。

NSDialogs 允许您弹出通过 ${NSD_Create*} 创建的控件的 hwnd (句柄)。EnableWindowhwnd 作为其参数之一。通过它,您可以轻松启用/禁用控件。

!include "nsDialogs.nsh"
!include "winmessages.nsh"
!include "logiclib.nsh"
OutFile "test.exe"Page Custom prevar dialog
var hwnd
var buttonFunction prensDialogs::Create 1018Pop $dialog${NSD_CreateCheckbox} 0 0 50% 6% "Enable button below"Pop $hwnd${NSD_OnClick} $hwnd EnDisableButton${NSD_CreateButton} 25% 25% 50% 50% "Hello World"Pop $buttonEnableWindow $button 0 # start out disablednsDialogs::Show
FunctionEndFunction EnDisableButtonPop $hwnd${NSD_GetState} $hwnd $0${If} $0 == 1EnableWindow $button 1${Else}EnableWindow $button 0${EndIf}
FunctionEndSection ""
SectionEnd

如何显示/隐藏控件

使用标准 NSIS ShowWindow 命令。

NSDialogs 允许您弹出通过 ${NSD_Create*} 创建的控件的 hwnd (句柄)。ShowWindow将 hwnd 作为其参数之一。通过它,您可以轻松显示/隐藏控件。

​
​
!include "nsDialogs.nsh"
!include "winmessages.nsh"
!include "logiclib.nsh"
OutFile "test.exe"Page Custom prevar dialog
var hwnd
var buttonFunction prensDialogs::Create 1018Pop $dialog${NSD_CreateCheckbox} 0 0 50% 6% "Show button below"Pop $hwnd${NSD_OnClick} $hwnd EnDisableButton${NSD_CreateButton} 25% 25% 50% 50% "Hello World"Pop $buttonShowWindow $button ${SW_HIDE} # start out hiddennsDialogs::Show
FunctionEndFunction EnDisableButtonPop $hwnd${NSD_GetState} $hwnd $0${If} $0 == 1ShowWindow $button ${SW_SHOW}${Else}ShowWindow $button ${SW_HIDE}${EndIf}
FunctionEndSection ""
SectionEnd​​

 如何创建一个文本居中的标签

文本居中 - 无论控件的大小如何,文本始终居中显示,这通常对于展示目的非常有用。使标签的文本居中对齐很简单,使用 ${NSD_AddStyle} 命令添加 ${SS_CENTER} 样式即可。

!include "nsDialogs.nsh"OutFile "$%temp%\temp.exe"var dialog
var hwnd
var nullPage custom TestFunction TestnsDialogs::Create 1018Pop $dialog${NSD_CreateLabel} 0 0 100% 20% "This line will be centered.$\nAnd so will this line."Pop $hwnd${NSD_AddStyle} $hwnd ${SS_CENTER}nsDialogs::Show
FunctionEndSection
SectionEnd

如何创建多行编辑(文本)控件 

虽然多行是控件的一个样式,但对于编辑(文本)控件来说,它是少数几种样式之一,无法在控件创建后设置,因此无法使用 ${NSD_AddStyle}。

相反,您需要手动创建控件:

!include "nsDialogs.nsh"
!include "winmessages.nsh"
!include "logiclib.nsh"
OutFile "test.exe"Page Custom prevar dialog
var hwndFunction prensDialogs::Create 1018Pop $dialog${NSD_CreateText} 0 0 100% 40% "This is NOT a$\r$\nmulti-line$\r$\nedit control"Pop $hwndnsDialogs::CreateControl EDIT \"${__NSD_Text_STYLE}|${WS_VSCROLL}|${ES_MULTILINE}|${ES_WANTRETURN}" \"${__NSD_Text_EXSTYLE}" \0 50% 100% 40% \"This IS a$\r$\nmulti-line$\r$\nedit control"Pop $hwndnsDialogs::Show
FunctionEndSection ""
SectionEnd

 或者,更简洁的方法是使用  NsDialogs_CreateTextMultiline  头文件:

!include "nsDialogs.nsh"
!include "nsDialogs_createTextMultiline.nsh"
!include "winmessages.nsh"
!include "logiclib.nsh"
OutFile "test.exe"Page Custom prevar dialog
var hwndFunction prensDialogs::Create 1018Pop $dialog${NSD_CreateText} 0 0 100% 40% "This is NOT a$\r$\nmulti-line$\r$\nedit control"Pop $hwnd${NSD_CreateTextMultiline} 0 50% 100% 40% "This IS a$\r$\nmulti-line$\r$\nedit control"Pop $hwndnsDialogs::Show
FunctionEndSection ""
SectionEnd

如何创建文本密码控件

请参阅 nsDialogs 文档 - 密码控件是默认支持的控件之一;${NSD_CreatePassword}

如何设置文本密码控件使用的字符

默认情况下,文本密码控件将使用星号(****)作为密码字符来掩盖文本(当'XPStyle off'时),或者使用圆点(••••)(当'XPStyle on'时)。您可以使用带有 EM_SETPASSWORDCHAR 标志的 SendMessage 来更改此字符。

密码字符由其 ASCII 或 UNICODE 码索引标识;请注意,您在安装程序中使用的字体可能不支持您希望使用的字符。

注意:如果将密码字符设置为 0(零),文本将不会被掩盖!您可以利用这一点在文本密码控件中切换文本的可见和掩盖状态。另请参阅如何在文本密码控制中隐藏/显示密码的条目。

!include "nsDialogs.nsh"
!include "winmessages.nsh"
!include "logiclib.nsh"
OutFile "test.exe"Page Custom prevar dialog
var hwndFunction prensDialogs::Create 1018Pop $dialog${NSD_CreatePassword} 0 0 50% 8% "This is a password field"Pop $hwndSendMessage $hwnd ${EM_SETPASSWORDCHAR} 149 0 # 在 ASCII 或 Unicode 编码中,149 指的是中等大小的圆点nsDialogs::Show
FunctionEndSection ""
SectionEnd

 如何在文本密码控件中隐藏/显示密码

通过使用带有 EM_SETPASSWORDCHAR 标志的 SendMessage 设置,通过将字符指定为 0(零),您可以让密码可见,而通过指定非零字符使密码再次不可见。

注意:更改掩码字符后,必须强制重绘密码控件。通常是通过隐藏然后使用 ShowWindow 显示控件来完成。
!include "nsDialogs.nsh"
!include "winmessages.nsh"
!include "logiclib.nsh"
OutFile "test.exe"Page Custom prevar dialog
var hwnd
var passwordControlFunction prensDialogs::Create 1018Pop $dialog${NSD_CreateCheckbox} 0 0 25% 8% "Show password"Pop $hwnd${NSD_OnClick} $hwnd ShowPassword${NSD_CreatePassword} 0 10% 50% 8% "This is a password field"Pop $passwordControlnsDialogs::Show
FunctionEndFunction ShowPasswordPop $hwnd${NSD_GetState} $hwnd $0ShowWindow $passwordControl ${SW_HIDE}${If} $0 == 1SendMessage $passwordControl ${EM_SETPASSWORDCHAR} 0 0${Else}SendMessage $passwordControl ${EM_SETPASSWORDCHAR} 42 0${EndIf}ShowWindow $passwordControl ${SW_SHOW}
FunctionEndSection ""
SectionEnd

注意:在启用 'XPStyle on' 的情况下,如果要重置ANSI构建中看到的“粗点”字符,不能使用标准的SendMessage(底层使用 SendMessageA),因为它是一个 Unicode 字符。可以使用 System 插件调用 SendMessageW 函数:

/* 9679是粗点字符 */

System::Call "user32::SendMessageW(i $hwnd, i ${EM_SETPASSWORDCHAR}, i 9679, i 0)"

如何创建仅数字的文本控件 

 请参阅 nsDialogs 文档 - 仅限数字的控件是默认支持的控件之一;${NSD_CreateNumber}

如何创建只读文本控件 

文本控件的只读状态可以使用带有 EM_SETREADONLY 标志的 SendMessage 来设置。

请注意,只读的编辑(文本)控件与禁用的文本控件不同。禁用的文本控件将其文本显示为灰色,而只读的文本控件则保持黑色,并显示在浅灰色背景上。此外,禁用的多行文本控件无法滚动。而只读的多行文本控件则可以滚动。

!include "nsDialogs.nsh"
!include "winmessages.nsh"
!include "logiclib.nsh"
OutFile "test.exe"Page Custom prevar dialog
var hwnd
var textControlFunction prensDialogs::Create 1018Pop $dialog${NSD_CreateCheckBox} 0 0 50% 6% "Set text field below read-only"Pop $hwnd${NSD_OnClick} $hwnd SetReadonly${NSD_CreateText} 0 12% 100% 8% "Hello World"Pop $textControlnsDialogs::Show
FunctionEndFunction SetReadonlyPop $hwnd${NSD_GetState} $hwnd $0SendMessage $textControl ${EM_SETREADONLY} $0 0
FunctionEndSection ""
SectionEnd

单选按钮 (Radio buttons)

单选按钮基本用法 

!include nsDialogs.nsh
Page Custom MyPageCreate MyPageLeaveVar StationChoiceFunction MyPageCreate
nsDialogs::Create 1018
Pop $0
${NSD_CreateFirstRadioButton} 0 0 40% 6% "NPR"
Pop $1
SendMessage $1 ${BM_CLICK} "" "" ; Must select a default
${NSD_CreateAdditionalRadioButton} 0 12% 40% 6% "BBC"
Pop $2
${IfThen} $StationChoice == "BBC" ${|} SendMessage $2 ${BM_CLICK} "" "" ${|}
nsDialogs::Show
FunctionEndFunction MyPageLeave
${NSD_GetChecked} $1 $3
${If} $3 <> ${BST_UNCHECKED}StrCpy $StationChoice "NPR"
${Else}StrCpy $StationChoice "BBC"
${EndIf}
FunctionEndSection
DetailPrint "Turning the dial to $StationChoice"
SectionEnd

根据单选按钮的变化更新页面 

!include nsDialogs.nsh
Page Custom MyPageCreateFunction MyPageCreate
nsDialogs::Create 1018
Pop $0; 组1
${NSD_CreateFirstRadioButton} 0 0 50% 12u "NPR"
Pop $1
${NSD_OnClick} $1 onStationChanged
${NSD_CreateAdditionalRadioButton} 0 14u 50% 12u "BBC"
Pop $2
${NSD_OnClick} $2 onStationChanged
${NSD_CreateLabel} 0 30u 80% 12u ""
Pop $3
SendMessage $1 ${BM_CLICK} "" "" ; 必须选择一个默认选项; 组2
${NSD_CreateFirstRadioButton} 0 50u 50% 12u "FM"
Pop $0 ; 仅用于演示,稍后不需要句柄
${NSD_CreateAdditionalRadioButton} 0 64u 50% 12u "AM"
Pop $0 ; 仅用于演示,稍后不需要句柄
SendMessage $0 ${BM_CLICK} "" "" ; 必须选择一个默认选项nsDialogs::Show
FunctionEndFunction onStationChanged
Pop $0
${NSD_GetChecked} $1 $0
${If} $0 <> ${BST_UNCHECKED}${NSD_SetText} $3 "America, f*(# yeah!" ;
${Else}${NSD_SetText} $3 "保持冷静,继续前行" ; Keep Calm and Carry On
${EndIf}
FunctionEnd

如何创建两组 RadioButton 

使用 ${NSD_AddStyle} 向每组的第一个单选按钮添加 WS_GROUP 样式。在 Windows 的 UI 处理中,如果没有定义组启动器,所有单选按钮都被视为同一组的一部分。

因此,要创建两个各有两个单选按钮的组,必须为每组指定一个组启动器,否则第三和第四个单选按钮将被视为第一组的一部分。

使用 ${NSD_AddStyle} 设置组启动器很简单,使用以下代码:

${NSD_AddStyle} $hwnd ${WS_GROUP}  # WS_GROUP 定义在 winmessages.nsh 中

示例: 

!include "nsDialogs.nsh"
!include "winmessages.nsh"
!include "logiclib.nsh"
OutFile "test.exe"Page Custom prevar dialog
var hwndFunction prensDialogs::Create 1018Pop $dialog${NSD_CreateRadioButton} 0 0 40% 6% "组 1,单选按钮 1"Pop $hwnd${NSD_AddStyle} $hwnd ${WS_GROUP}${NSD_CreateRadioButton} 0 12% 40% 6% "组 1,单选按钮 2"Pop $hwnd${NSD_CreateRadioButton} 50% 0 40% 6% "组 2,单选按钮 1"Pop $hwnd${NSD_AddStyle} $hwnd ${WS_GROUP}${NSD_CreateRadioButton} 50% 12% 40% 6% "组 2,单选按钮 2"Pop $hwndnsDialogs::Show
FunctionEndSection ""
SectionEnd

如何轻松处理单选按钮的选择 

通常,你不希望为每个单选按钮指定单独的 OnClick 函数... 

!include "nsDialogs.nsh"
!include "winmessages.nsh"
!include "logiclib.nsh"
OutFile "test.exe"Page Custom prevar dialog
var hwndFunction prensDialogs::Create 1018Pop $dialog${NSD_CreateRadioButton} 0 0 40% 6% "Group 1, Radio 1"Pop $hwnd${NSD_AddStyle} $hwnd ${WS_GROUP}${NSD_OnClick} $hwnd Group1Radio1Click${NSD_CreateRadioButton} 0 12% 40% 6% "Group 1, Radio 2"Pop $hwnd${NSD_OnClick} $hwnd Group1Radio2ClicknsDialogs::Show
FunctionEndFunction Group1Radio1ClickPop $hwndMessageBox MB_OK "onClick:Group1Radio1"
FunctionEnd
Function Group1Radio2ClickPop $hwndMessageBox MB_OK "onClick:Group1Radio2"
FunctionEndSection ""
SectionEnd

但是唯一明显的替代方法似乎是将每个单选按钮放在不同的变量中,并在回调函数调用时将堆栈上的 hwnd 与该变量进行比较。

!include "nsDialogs.nsh"
!include "winmessages.nsh"
!include "logiclib.nsh"
OutFile "test.exe"Page Custom prevar dialog
var hwndvar Group1Radio1
var Group1Radio2Function prensDialogs::Create 1018Pop $dialog${NSD_CreateRadioButton} 0 0 40% 6% "组 1, 单选 1"Pop $Group1Radio1${NSD_AddStyle} $Group1Radio1 ${WS_GROUP}${NSD_OnClick} $Group1Radio1 RadioClick${NSD_CreateRadioButton} 0 12% 40% 6% "组 1, 单选 2"Pop $Group1Radio2${NSD_OnClick} $Group1Radio2 RadioClicknsDialogs::Show
FunctionEndFunction RadioClickPop $hwnd${If} $hwnd == $Group1Radio1MessageBox MB_OK "点击:组 1 单选 1"${ElseIf} $hwnd == $Group1Radio2MessageBox MB_OK "点击:组 1 单选 2"${EndIf}
FunctionEndSection ""
SectionEnd

然而,你可以通过使用 nsDialogs 的 getUserData 和 setUserData 命令来消除这种情况。使用这些 *UserData 命令,你可以将数据存储在控件中,并在以后轻松检索这些数据。

为了简化这些命令的使用,我们将使用 NsDialogs UserData 的头文件。

!include "nsDialogs.nsh"
!include "winmessages.nsh"
!include "logiclib.nsh"
OutFile "test.exe"Page Custom prevar dialog
var hwndFunction prensDialogs::Create 1018Pop $dialog${NSD_CreateRadioButton} 0 0 40% 6% "组 1, 单选 1"Pop $hwnd${NSD_AddStyle} $hwnd ${WS_GROUP}${NSD_SetUserData} $hwnd "Group1Radio1"${NSD_OnClick} $hwnd RadioClick${NSD_CreateRadioButton} 0 12% 40% 6% "组 1, 单选 2"Pop $hwnd${NSD_SetUserData} $hwnd "Group1Radio2"${NSD_OnClick} $hwnd RadioClicknsDialogs::Show
FunctionEndFunction RadioClickPop $hwnd${NSD_GetUserData} $hwnd $0${If} $0 == "Group1Radio1"MessageBox MB_OK "点击:组 1 单选 1"${ElseIf} $0 == "Group1Radio2"MessageBox MB_OK "点击:组 1 单选 2"${EndIf}
FunctionEndSection ""
SectionEnd

使用这种方法,你可以轻松地将变量设置为存储在单选按钮控件上的内部字符串,而不需要在 OnClick 事件函数中使用任何 If-ElseIf-EndIf 或 Case 选择。

!include "nsDialogs.nsh"
!include "winmessages.nsh"
!include "logiclib.nsh"
OutFile "test.exe"Page Custom pre postvar dialog
var hwnd
var minorFunction prensDialogs::Create 1018Pop $dialog${NSD_CreateRadioButton} 0 0 40% 6% "我已年满 14 岁"Pop $hwnd${NSD_AddStyle} $hwnd ${WS_GROUP}${NSD_SetUserData} $hwnd "false"${NSD_OnClick} $hwnd RadioClick${NSD_CreateRadioButton} 0 12% 40% 6% "我未满 14 岁"Pop $hwnd${NSD_SetUserData} $hwnd "true"${NSD_OnClick} $hwnd RadioClicknsDialogs::Show
FunctionEndFunction RadioClickPop $hwnd${NSD_GetUserData} $hwnd $minor
FunctionEndFunction post${If} $minor == ""MessageBox MB_OK "请选择你的年龄组"Abort${ElseIf} $minor == trueMessageBox MB_OK "安装将继续进行,内容适合你的年龄"${Else}MessageBox MB_OK "安装将正常进行"${EndIf}
FunctionEndSection ""
SectionEnd

进度条

如何控制进度条控件(使用绝对值) 您可以使用 sendMessage 和进度条控件的消息来控制进度条。这些消息几乎都在 NSIS 附带的 WinMessages.nsh 头文件中定义,因此请务必包含此头文件。

至少有一个例外,它非常有用,因为它可以减少代码量并使您的源代码更容易阅读,那就是 PBM_SETRANGE32PBM_SETRANGE32 允许您只用两个数字设置起始和结束范围,而不必像 PBM_SETRANGE 那样使用 WinDef.nsh 中的 ${MakeLong}

为了更新进度条的值,您需要使用 nsDialogs 计时器来调用处理实际处理的函数。此计时器仅调用一次。

下面是一个简单的示例,该示例创建了一个范围从 0(零)到 100 的进度条,用于典型的百分比增加,并将进度设置为 25%、50%、75% 和 100%,使用 Sleep 命令来模拟处理发生的情况——通常这可能是其他 NSIS 调用或在主安装之前调用外部应用程序/安装程序等。

!include "WinMessages.nsh"
!include "MUI2.nsh"
!include "nsDialogs.nsh"OutFile "test.exe"Section
SectionEndVar dialog
Var hwnd
Var nullPage Custom page.custom
Function page.customnsDialogs::Create 1018Pop $dialog${NSD_CreateProgressBar} 0 0 100% 10% "Test"Pop $hwnd${NSD_CreateTimer} NSD_Timer.Callback 10nsDialogs::Show
FunctionEndFunction NSD_Timer.Callback${NSD_KillTimer} NSD_Timer.CallbackSendMessage $hwnd ${PBM_SETRANGE32} 0 100SendMessage $hwnd ${PBM_SETPOS} 25 0Sleep 2000SendMessage $hwnd ${PBM_SETPOS} 50 0Sleep 2000SendMessage $hwnd ${PBM_SETPOS} 75 0Sleep 2000SendMessage $hwnd ${PBM_SETPOS} 100 0
FunctionEnd!insertmacro MUI_LANGUAGE "English"

如何控制进度条控件(使用步进值) 

上一个示例的一个缺点是,您必须始终跟踪百分比,而这些百分比可能并不重要,只要用户知道有进度即可。一个例子是,在复制/粘贴代码块时,跟踪百分比可能会变得棘手。您可能会突然发现自己的进度条从 0% 到 50%,然后回到 25%,再上升到 75%。

解决这个问题的一个相当简单的方法是使用步进进度条。这种方法允许您定义一个步进增量值,并简单地调用步进函数来逐步增加进度条的值。以下是使用这种方法的示例,其功能与前面的示例相同。请注意,我们将范围设置为函数中预期的步数。

!include "WinMessages.nsh"
!include "MUI2.nsh"
!include "nsDialogs.nsh"OutFile "test.exe"Section
SectionEndVar dialog
Var hwnd
Var nullPage Custom page.custom
Function page.customnsDialogs::Create 1018Pop $dialog${NSD_CreateProgressBar} 0 0 100% 10% "测试"Pop $hwnd${NSD_CreateTimer} NSD_Timer.Callback 10nsDialogs::Show
FunctionEndFunction NSD_Timer.Callback${NSD_KillTimer} NSD_Timer.CallbackSendMessage $hwnd ${PBM_SETRANGE32} 0 4SendMessage $hwnd ${PBM_SETSTEP} 1 0SendMessage $hwnd ${PBM_STEPIT} 0 0Sleep 2000SendMessage $hwnd ${PBM_STEPIT} 0 0Sleep 2000SendMessage $hwnd ${PBM_STEPIT} 0 0Sleep 2000SendMessage $hwnd ${PBM_STEPIT} 0 0SendMessage $hwnd ${PBM_SETPOS} 4 0
FunctionEnd!insertmacro MUI_LANGUAGE "English"

请注意,在最后,我们仍然将进度设置为 100%。这是因为您的函数中可能有一些条件步骤。如果您忘记步进进度条,那么进度值将不会达到 100%。这是一个经常报告的用户界面问题,用户抱怨即使过程完成了,进度条仍然停留在少于 100% 的位置。

但是,请注意不要使用比在 PBM_SETRANGE32 调用中指定的步数更多的步骤,因为之后的任何步骤都会显示为 100%,而没有任何明显的进展。

如何创建一个跑马灯(无限循环)进度条控件 

有时您可能不知道进度 - 例如,您正在执行一个可能需要一些时间的任务,但无法确定任务进行到哪一步。在这种情况下,您可能希望使用一个所谓的跑马灯进度条,它只是从左到右无限循环。

有一个需要注意的事项:除非您使用带有 XP 样式的界面(另见 XPStyle),否则您不能使用跑马灯进度条。

除此之外,通过使用 ${NSD_AddStyle} 向进度条添加 PBS_MARQUEE 样式。

以下是一个这样的示例:

!include "WinMessages.nsh"
!include "MUI2.nsh"
!include "nsDialogs.nsh"OutFile "test.exe"Section
SectionEndVar dialog
Var hwnd
Var null!define PBS_MARQUEE 0x08Page Custom page.custom
Function page.customnsDialogs::Create 1018Pop $dialog${NSD_CreateProgressBar} 0 0 100% 10% "测试"Pop $hwnd${NSD_AddStyle} $hwnd ${PBS_MARQUEE}${NSD_CreateTimer} NSD_Timer.Callback 10nsDialogs::Show
FunctionEndFunction NSD_Timer.Callback${NSD_KillTimer} NSD_Timer.Callback ; 关闭定时器SendMessage $hwnd ${PBM_SETMARQUEE} 1 50 ; start=1|stop=0 间隔(ms)=+N_again:MessageBox MB_YESNO "停止跑马灯?" IDNO _againSendMessage $hwnd ${PBM_SETMARQUEE} 0 0FunctionEnd!insertmacro MUI_LANGUAGE "English"

请注意,跑马灯进度条总是从左到右运行 - 您不能将其设置为其他任何位置。 

如何让控件接收快捷键(alt+字母)组合 

只有带标签的控件可以分配快捷键,只需在其标题中包含一个 & 符号。例如: 

${NSD_CreateCheckbox} 3% 3% 20% 8% "The hot&key here is alt+k"

但是,当在 NSIS 中首次导航到页面时,NSIS 对话框是获得焦点的,而不是内部的 nsDialogs 对话框。因此,在告诉 nsDialogs 显示之前,请先将焦点设置到 nsDialogs 对话框: 

nsDialogs::Create 1018
Pop $dialog ; 假设您有一个 'dialog' 变量!
; 后续代码在这里
SendMessage $dialog ${WM_SETFOCUS} $HWNDPARENT 0
nsDialogs::Show

NSIS 对话框仍然会处理例如 alt+N 用于下一步按钮,因为如果当前焦点的窗口没有对快捷键事件作出反应,这些事件会简单地“冒泡”到父窗口。(提示:这意味着您不应该为 B(ack) 或 N(ext) 字母设置任何快捷键!)

使用这些方法,您可以轻松创建一个可以完全通过键盘操作的安装程序。

 

 

 

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/46161.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

代码随想录:图论_01基础

图论基础 图的存储 邻接矩阵 使用 二维数组 来表示图结构。 邻接矩阵是从节点的角度来表示图&#xff0c;有多少节点就申请多大的二维数组。为了节点标号和下标对齐&#xff0c;我们申请 n 1 * n 1 这么大的二维数组。 vector<vector<int>> graph(n 1, vector…

特斯拉的选择:.NET技术栈的工业级魅力

简述 在全球科技巨头的竞技场上&#xff0c;特斯拉以其创新精神和卓越技术引领着电动汽车和可再生能源行业。而在这场技术革命的背后&#xff0c;特斯拉的技术栈选择尤为引人注目。本文将深入探讨特斯拉为何青睐.NET技术栈&#xff0c;并分析这一选择背后的战略考量。 技术栈的…

【Linux 文件读写描述符重定向 Linux 一切皆文件缓冲区】

文章目录 一、文件的读写操作二、文件描述符三、文件重定向四、理解 Linux 一切皆文件五、文件缓冲区 一、文件的读写操作 文件内容属性 当文件没有被操作的时候&#xff0c;一般文件还是在磁盘当中 文件操作文件内容的操作文件属性的操作&#xff0c;文件操作有可能即改变内容…

二叉树---后序遍历(递归与迭代)

题目&#xff1a;给你一棵二叉树的根节点 root &#xff0c;返回其节点值的 后序遍历 。 思路一&#xff1a;递归法。 代码&#xff1a; public List<Integer> postorderTraversal(TreeNode root) {List<Integer> resultnew ArrayList<>();postOrder(root,…

如何利用Gunicorn的日志记录监控Web应用

如何利用Gunicorn的日志记录监控Web应用 引言 在构建和维护Web应用时&#xff0c;日志记录是一个至关重要的工具。它不仅可以帮助开发者了解应用的运行状态&#xff0c;还能迅速定位和解决问题。Gunicorn作为一个流行的Python WSGI HTTP服务器&#xff0c;提供了丰富的日志记…

代码运行故障排除:PyCharm中的问题解决指南

代码运行故障排除&#xff1a;PyCharm中的问题解决指南 引言 PyCharm&#xff0c;作为一款流行的集成开发环境&#xff08;IDE&#xff09;&#xff0c;提供了强大的工具来支持Python开发。然而&#xff0c;即使是最先进的IDE也可能遇到代码无法运行的问题。这些问题可能由多…

《python程序语言设计》2018版第5章第55题利用turtle黑白棋盘。可读性还是最重要的。

今天是我从2024年2月21日开始第9次做《python程序语言设计》作者梁勇 第5章 从2019年夏天的偶然了解python到2020年第一次碰到第5章第一题。彻底放弃。再到半年后重新从第一章跑到第五章&#xff0c;一遍一遍一直到今天2024.7.14日第9次刷第五章。 真的每次刷完第五章感觉好像…

【C语言】<常量> 之群英荟萃

目录 1. 数值常量&#xff08;Numeric Constants&#xff09;1.1 整型常量&#xff08;Integer Constants&#xff09;1.2 浮点型常量&#xff08;Floating-point Constants&#xff09; 2. 字符常量&#xff08;Character Constants&#xff09;3. 字符串常量&#xff08;Stri…

【JavaScript】解决 JavaScript 语言报错:Uncaught SyntaxError: Unexpected token

文章目录 一、背景介绍常见场景 二、报错信息解析三、常见原因分析1. 缺少必要的语法元素2. 使用了不正确的字符或符号3. JSON 格式错误4. 字符串未正确闭合 四、解决方案与预防措施1. 检查语法元素2. 正确使用符号和字符3. 修正 JSON 格式4. 字符串闭合 五、示例代码和实践建议…

android13 文件管理器无法安装apk 奔溃问题

总纲 android13 rom 开发总纲说明 目录 1.前言 2.我们简单写个apk测试下 3.排查客户apk 4.frameworks源码排查 5.编译验证 6.彩蛋 1.前言 客户提供的文件管理apk不能安装apk文件,一点击就奔溃。 2.我们简单写个apk测试下 private void installApk(File apkFile) {i…

映美精黑白相机IFrameQueueBuffer转halcon的HObject

映美精黑白相机&#xff0c;用wpfhalcon开发取图 1.到官网下载&#xff0c;开发包 1sdk 2c开发例子 3c#开发例子 引入TIS.Imaging.ICImagingControl35.dll 3.ICImagingControl使用这个类控制相机 /// <summary> /// 相机控制 /// </summary> public ICImagingC…

MySQL的插入(DML)

1.给指定字段添加数据 这个就是&#xff0c;想插入所对应的字段&#xff0c;就插入所对应的数值。先把字段列出来&#xff0c;不一定是全部的字段&#xff0c; 然后插入想要的值&#xff0c;注意&#xff0c;只能插入一行。 INSERT INTO 表名 (字段1,字段2,.....) VALUES(值…

将swagger注解导入apifox的IDEA配置

在使用IDEA开发中&#xff0c;经常需要将后端接口导出到Apifox&#xff0c;以便于测试。将swagger注解内容导出到Apifox中&#xff0c;需要进行以下设置: file->settting打开对话框&#xff0c;选择Other Settings -> Apifox Help&#xff0c;如下图&#xff1a; 2.选…

【Python】ftplib的使用

仅描述基础要点&#xff0c;备忘。 python自带ftplib库&#xff0c;可实现ftp读写。 1 要点 ftp未使用默认端口21时&#xff0c;需显示指定端口。ftp路径带有中文&#xff0c;可能需要设置ftp的encoding属性为 gbk。ftplib不支持递归创建目录&#xff0c;需手动创建层级目录…

NAS 必备导航页 Homarr 可视化配置 布局简单且美观

本文首发于只抄博客,欢迎点击原文链接了解更多内容。 前言 之前给大家介绍了 Homepage,但是 Homepage 的每一个链接的添加以及整体的布局都依赖 yaml 文件,而且官方文档关于 yaml 配置项也只有英文。对于没有基础的用户来说,想要配置成自己喜欢的布局有些困难。而今天介绍…

【软件测试】自动化测试常用函数 -- 详解

一、WebDriver API 一个简单自动化脚本的构成&#xff1a; 脚本解析 # coding utf-8 from selenium import webdriver import time browser webdriver.Firefox() time.sleep(3) browser.get("http://www.baidu.com") time.sleep(3) browser.find_element_by_id(…

数据实时化是必要还是偏见?

数据实时化是必要还是偏见&#xff1f; 一、前言二、数据仓库的起源三、数据架构的演进四、数据实时化的必要性五、总结 本文主要基于数据仓库的起源和数据架构的演进来聊聊&#xff0c;数据实时化是否真的必要&#xff1f;是"过度优化"、“实时偏见"还是"…

元组-预习

# 元组 tuple() # 定义 tu () # 空元组 tu1 (1, 2, 3) # 一旦初始化&#xff0c;不可再改变# 索引 print(tu1[0]) # 1 print(tu1[-1]) # 3 # print(tu1[3]) # 报错 超出索引范围# 切片 tu2 (1, 2, 3, 4, 5) print(tu2[0:2])# 不允许改变tu2[0] 6 # TypeError: tuple …

【数据结构】手写快速排序

一、理念 什么是快速排序&#xff1f; 首先确立pivot&#xff0c;比如下图位于末尾 然后i遍历3到6 在3的时候&#xff0c;j指向i前面一位 如果3<5(pivot)&#xff0c;那么j&#xff0c;同时将i与j指向的交换&#xff0c;第一次交换是原地不动 一直到遇见9&#xff0c;…

数据结构和算法(0-1)----递归

定义​ 递归是一种在程序设计中常用的技术&#xff0c;它允许一个函数调用自身来解决问题。递归通常用于解决那些可以被分解为相似的子问题的问题&#xff0c;这些问题的解决方式具有自相似性。在数据结构和算法中&#xff0c;递归是一种重要的解决问题的方法&#xff0c;尤其是…