Coverage for src / ezqt_widgets / widgets / input / auto_complete_input.py: 98.55%

65 statements  

« prev     ^ index     » next       coverage.py v7.13.5, created at 2026-03-31 10:03 +0000

1# /////////////////////////////////////////////////////////////// 

2# AUTO_COMPLETE_INPUT - Auto-Complete Input Widget 

3# Project: ezqt_widgets 

4# /////////////////////////////////////////////////////////////// 

5 

6""" 

7Auto-complete input widget module. 

8 

9Provides a QLineEdit subclass with autocompletion support for PySide6 

10applications. 

11""" 

12 

13from __future__ import annotations 

14 

15# /////////////////////////////////////////////////////////////// 

16# IMPORTS 

17# /////////////////////////////////////////////////////////////// 

18# Standard library imports 

19from typing import Any 

20 

21# Third-party imports 

22from PySide6.QtCore import QStringListModel, Qt 

23from PySide6.QtWidgets import QCompleter, QLineEdit 

24 

25# Local imports 

26from ...types import WidgetParent 

27 

28# /////////////////////////////////////////////////////////////// 

29# CLASSES 

30# /////////////////////////////////////////////////////////////// 

31 

32 

33class AutoCompleteInput(QLineEdit): 

34 """QLineEdit subclass with autocompletion support. 

35 

36 Provides a text input widget with autocompletion functionality. 

37 You can provide a list of suggestions (strings) to be used for 

38 autocompletion. 

39 

40 Args: 

41 parent: The parent widget (default: None). 

42 suggestions: List of strings to use for autocompletion 

43 (default: empty list). 

44 case_sensitive: Whether the autocompletion is case sensitive 

45 (default: False). 

46 filter_mode: Filter mode for completion 

47 (default: Qt.MatchFlag.MatchContains). 

48 completion_mode: Completion mode 

49 (default: QCompleter.CompletionMode.PopupCompletion). 

50 *args: Additional arguments passed to QLineEdit. 

51 **kwargs: Additional keyword arguments passed to QLineEdit. 

52 

53 Properties: 

54 suggestions: Get or set the list of suggestions for autocompletion. 

55 case_sensitive: Get or set whether autocompletion is case sensitive. 

56 filter_mode: Get or set the filter mode for completion. 

57 completion_mode: Get or set the completion mode. 

58 

59 Example: 

60 >>> from ezqt_widgets import AutoCompleteInput 

61 >>> inp = AutoCompleteInput(suggestions=["Alice", "Bob", "Charlie"]) 

62 >>> inp.case_sensitive = False 

63 >>> inp.suggestions = ["Alice", "Bob", "Charlie", "Dave"] 

64 >>> inp.show() 

65 """ 

66 

67 # /////////////////////////////////////////////////////////////// 

68 # INIT 

69 # /////////////////////////////////////////////////////////////// 

70 

71 def __init__( 

72 self, 

73 parent: WidgetParent = None, 

74 suggestions: list[str] | None = None, 

75 case_sensitive: bool = False, 

76 filter_mode: Qt.MatchFlag = Qt.MatchFlag.MatchContains, 

77 completion_mode: QCompleter.CompletionMode = QCompleter.CompletionMode.PopupCompletion, 

78 *args: Any, 

79 **kwargs: Any, 

80 ) -> None: 

81 """Initialize the auto-complete input.""" 

82 super().__init__(parent, *args, **kwargs) 

83 

84 # Initialize properties 

85 self._suggestions: list[str] = suggestions or [] 

86 self._case_sensitive: bool = case_sensitive 

87 self._filter_mode: Qt.MatchFlag = filter_mode 

88 self._completion_mode: QCompleter.CompletionMode = completion_mode 

89 

90 # Setup completer 

91 self._setup_completer() 

92 

93 # ------------------------------------------------ 

94 # PRIVATE METHODS 

95 # ------------------------------------------------ 

96 

97 def _setup_completer(self) -> None: 

98 """Setup the completer with current settings.""" 

99 self._completer = QCompleter(self) 

100 self._model = QStringListModel(self._suggestions, self) 

101 

102 # Configure completer 

103 self._completer.setModel(self._model) 

104 self._completer.setCaseSensitivity( 

105 Qt.CaseSensitivity.CaseSensitive 

106 if self._case_sensitive 

107 else Qt.CaseSensitivity.CaseInsensitive 

108 ) 

109 self._completer.setFilterMode(self._filter_mode) 

110 self._completer.setCompletionMode(self._completion_mode) 

111 self.setCompleter(self._completer) 

112 

113 # /////////////////////////////////////////////////////////////// 

114 # PROPERTIES 

115 # /////////////////////////////////////////////////////////////// 

116 

117 @property 

118 def suggestions(self) -> list[str]: 

119 """Get the list of suggestions. 

120 

121 Returns: 

122 A copy of the current suggestions list. 

123 """ 

124 return self._suggestions.copy() 

125 

126 @suggestions.setter 

127 def suggestions(self, value: list[str]) -> None: 

128 """Set the list of suggestions. 

129 

130 Args: 

131 value: The new list of suggestions. 

132 """ 

133 self._suggestions = value or [] 

134 self._model.setStringList(self._suggestions) 

135 

136 @property 

137 def case_sensitive(self) -> bool: 

138 """Get whether autocompletion is case sensitive. 

139 

140 Returns: 

141 True if case sensitive, False otherwise. 

142 """ 

143 return self._case_sensitive 

144 

145 @case_sensitive.setter 

146 def case_sensitive(self, value: bool) -> None: 

147 """Set whether autocompletion is case sensitive. 

148 

149 Args: 

150 value: Whether to enable case sensitivity. 

151 """ 

152 self._case_sensitive = bool(value) 

153 self._completer.setCaseSensitivity( 

154 Qt.CaseSensitivity.CaseSensitive 

155 if self._case_sensitive 

156 else Qt.CaseSensitivity.CaseInsensitive 

157 ) 

158 

159 @property 

160 def filter_mode(self) -> Qt.MatchFlag: 

161 """Get the filter mode for completion. 

162 

163 Returns: 

164 The current filter mode. 

165 """ 

166 return self._filter_mode 

167 

168 @filter_mode.setter 

169 def filter_mode(self, value: Qt.MatchFlag) -> None: 

170 """Set the filter mode for completion. 

171 

172 Args: 

173 value: The new filter mode. 

174 """ 

175 self._filter_mode = value 

176 self._completer.setFilterMode(self._filter_mode) 

177 

178 @property 

179 def completion_mode(self) -> QCompleter.CompletionMode: 

180 """Get the completion mode. 

181 

182 Returns: 

183 The current completion mode. 

184 """ 

185 return self._completion_mode 

186 

187 @completion_mode.setter 

188 def completion_mode(self, value: QCompleter.CompletionMode) -> None: 

189 """Set the completion mode. 

190 

191 Args: 

192 value: The new completion mode. 

193 """ 

194 self._completion_mode = value 

195 self._completer.setCompletionMode(self._completion_mode) 

196 

197 # /////////////////////////////////////////////////////////////// 

198 # PUBLIC METHODS 

199 # /////////////////////////////////////////////////////////////// 

200 

201 def addSuggestion(self, suggestion: str) -> None: 

202 """Add a suggestion to the list. 

203 

204 Args: 

205 suggestion: The suggestion string to add. 

206 """ 

207 if suggestion and suggestion not in self._suggestions: 

208 self._suggestions.append(suggestion) 

209 self._model.setStringList(self._suggestions) 

210 

211 def removeSuggestion(self, suggestion: str) -> None: 

212 """Remove a suggestion from the list. 

213 

214 Args: 

215 suggestion: The suggestion string to remove. 

216 """ 

217 if suggestion in self._suggestions: 217 ↛ exitline 217 didn't return from function 'removeSuggestion' because the condition on line 217 was always true

218 self._suggestions.remove(suggestion) 

219 self._model.setStringList(self._suggestions) 

220 

221 def clearSuggestions(self) -> None: 

222 """Clear all suggestions.""" 

223 self._suggestions.clear() 

224 self._model.setStringList(self._suggestions) 

225 

226 # /////////////////////////////////////////////////////////////// 

227 # STYLE METHODS 

228 # /////////////////////////////////////////////////////////////// 

229 

230 def refreshStyle(self) -> None: 

231 """Refresh the widget's style. 

232 

233 Useful after dynamic stylesheet changes. 

234 """ 

235 self.style().unpolish(self) 

236 self.style().polish(self) 

237 self.update() 

238 

239 

240# /////////////////////////////////////////////////////////////// 

241# PUBLIC API 

242# /////////////////////////////////////////////////////////////// 

243 

244__all__ = ["AutoCompleteInput"]