feat(input): 输入框右键菜单(剪切/复制/粘贴/全选)
QML 默认 TextField / TextArea 不带右键菜单(只能 Ctrl+V/C/X),跟旧 QWidget
版的体验差。补:
ThemedTextField (复用组件,覆盖登录用户名 + 款式词库添加输入):
TapHandler acceptedButtons:RightButton 弹 Menu,4 项:
剪切 / 复制 / 粘贴 / 全选
密码框 (echoMode === TextInput.Password) 时 剪切 / 复制 disabled,
防泄漏;粘贴 / 全选 仍可用(密码管理器粘贴常用)
ImageGenTab.qml promptArea (TextArea):
同样的 Menu + TapHandler,因为 promptArea 不通过 ThemedTextField 走
注:HistoryTab 详情 prompt 只读区已有 "
复制" 按钮覆盖复制需求;
StyleDesignerTab 的 Prompt 预览同样只读,旁边有字数显示,先不改。
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Showing
2 changed files
with
70 additions
and
0 deletions
| ... | @@ -600,12 +600,46 @@ Item { | ... | @@ -600,12 +600,46 @@ Item { |
| 600 | font.pointSize: App.Theme.fontBase | 600 | font.pointSize: App.Theme.fontBase |
| 601 | color: App.Theme.textPrimary | 601 | color: App.Theme.textPrimary |
| 602 | wrapMode: TextArea.Wrap | 602 | wrapMode: TextArea.Wrap |
| 603 | selectionColor: App.Theme.accent | ||
| 604 | selectedTextColor: App.Theme.textOnAccent | ||
| 603 | background: Rectangle { | 605 | background: Rectangle { |
| 604 | color: App.Theme.bgSubtle | 606 | color: App.Theme.bgSubtle |
| 605 | radius: App.Theme.radiusMd | 607 | radius: App.Theme.radiusMd |
| 606 | border.width: 1 | 608 | border.width: 1 |
| 607 | border.color: App.Theme.borderDefault | 609 | border.color: App.Theme.borderDefault |
| 608 | } | 610 | } |
| 611 | |||
| 612 | // 右键编辑菜单 | ||
| 613 | Menu { | ||
| 614 | id: promptEditMenu | ||
| 615 | MenuItem { | ||
| 616 | text: "剪切" | ||
| 617 | enabled: promptArea.selectedText.length > 0 | ||
| 618 | onTriggered: promptArea.cut() | ||
| 619 | } | ||
| 620 | MenuItem { | ||
| 621 | text: "复制" | ||
| 622 | enabled: promptArea.selectedText.length > 0 | ||
| 623 | onTriggered: promptArea.copy() | ||
| 624 | } | ||
| 625 | MenuItem { | ||
| 626 | text: "粘贴" | ||
| 627 | enabled: promptArea.canPaste | ||
| 628 | onTriggered: promptArea.paste() | ||
| 629 | } | ||
| 630 | MenuSeparator {} | ||
| 631 | MenuItem { | ||
| 632 | text: "全选" | ||
| 633 | enabled: promptArea.length > 0 | ||
| 634 | onTriggered: promptArea.selectAll() | ||
| 635 | } | ||
| 636 | } | ||
| 637 | |||
| 638 | TapHandler { | ||
| 639 | acceptedButtons: Qt.RightButton | ||
| 640 | gesturePolicy: TapHandler.WithinBounds | ||
| 641 | onTapped: promptEditMenu.popup() | ||
| 642 | } | ||
| 609 | } | 643 | } |
| 610 | } | 644 | } |
| 611 | } | 645 | } | ... | ... |
| ... | @@ -26,4 +26,40 @@ TextField { | ... | @@ -26,4 +26,40 @@ TextField { |
| 26 | ColorAnimation { duration: 100 } | 26 | ColorAnimation { duration: 100 } |
| 27 | } | 27 | } |
| 28 | } | 28 | } |
| 29 | |||
| 30 | // 右键弹编辑菜单(剪切 / 复制 / 粘贴 / 全选) | ||
| 31 | // 密码框 (echoMode === TextInput.Password) 时禁用 复制 / 剪切 防泄漏 | ||
| 32 | Menu { | ||
| 33 | id: editMenu | ||
| 34 | |||
| 35 | MenuItem { | ||
| 36 | text: "剪切" | ||
| 37 | enabled: control.selectedText.length > 0 | ||
| 38 | && control.echoMode !== TextInput.Password | ||
| 39 | onTriggered: control.cut() | ||
| 40 | } | ||
| 41 | MenuItem { | ||
| 42 | text: "复制" | ||
| 43 | enabled: control.selectedText.length > 0 | ||
| 44 | && control.echoMode !== TextInput.Password | ||
| 45 | onTriggered: control.copy() | ||
| 46 | } | ||
| 47 | MenuItem { | ||
| 48 | text: "粘贴" | ||
| 49 | enabled: control.canPaste | ||
| 50 | onTriggered: control.paste() | ||
| 51 | } | ||
| 52 | MenuSeparator {} | ||
| 53 | MenuItem { | ||
| 54 | text: "全选" | ||
| 55 | enabled: control.length > 0 | ||
| 56 | onTriggered: control.selectAll() | ||
| 57 | } | ||
| 58 | } | ||
| 59 | |||
| 60 | TapHandler { | ||
| 61 | acceptedButtons: Qt.RightButton | ||
| 62 | gesturePolicy: TapHandler.WithinBounds | ||
| 63 | onTapped: editMenu.popup() | ||
| 64 | } | ||
| 29 | } | 65 | } | ... | ... |
-
Please register or sign in to post a comment