@@ -100,9 +100,9 @@ def run(self):
100
100
self .QTableWidgetSetSort .emit (True )
101
101
# mutex.unlock()
102
102
103
- def stop (self ):
104
- self .quit ()
105
- self .wait (3000 )
103
+ # def stop(self):
104
+ # self.quit()
105
+ # self.wait(3000)
106
106
107
107
# 모듈화에 문제가 생겨서 우선 하드 코딩
108
108
@@ -113,7 +113,7 @@ def resource_path(relative_path):
113
113
return os .path .join (base_path , relative_path )
114
114
115
115
116
- # Main UI Load
116
+ # Main UI Compile & Load
117
117
118
118
# fmt: off
119
119
@@ -124,6 +124,52 @@ def resource_path(relative_path):
124
124
125
125
# fmt: on
126
126
127
+ # SearchWindow
128
+
129
+
130
+ class SearchWindow (QMainWindow , Ui_MainWindow ):
131
+ filtering = pyqtSignal (str ) # 필터링 시그널
132
+
133
+ # 100,100 창으로 설정
134
+ def __init__ (self ):
135
+ super ().__init__ ()
136
+ self .initUI ()
137
+
138
+ def txt_id_enter (self ):
139
+ # 현재 검색값을 시그널로 Main윈도우에 넘기기
140
+ self .filtering .emit (self .txt_keyword .text ())
141
+
142
+ def initUI (self ):
143
+ self .setWindowTitle ('Search Window' )
144
+
145
+ # 입력창 추가
146
+ self .txt_keyword = QLineEdit (self )
147
+ self .txt_keyword .move (0 , 0 )
148
+ self .txt_keyword .resize (200 , 20 )
149
+
150
+ # QlineEdit CSS 추가
151
+ self .setStyleSheet (
152
+ r"QLineEdit { border: 4px solid padding: 4px } QLineEdit: focus{ border: 4px solid rgb(0, 170, 255) }" )
153
+
154
+ # 타이틀창 간소화 하기
155
+ self .setWindowFlags (Qt .WindowTitleHint | Qt .WindowCloseButtonHint )
156
+
157
+ # 아이콘 main.ico 로 창 설정
158
+ self .setWindowIcon (QIcon (resource_path ('main.ico' )))
159
+
160
+ # txt_id 엔터 시그널 연결
161
+ self .txt_keyword .returnPressed .connect (self .txt_id_enter )
162
+
163
+ # self.move(300, 300)
164
+ self .resize (200 , 20 )
165
+ self .show ()
166
+
167
+ # 엔터키 누르면 종료
168
+ def keyPressEvent (self , e ):
169
+ # esc 누르면 종료
170
+ if e .key () == QtCore .Qt .Key_Escape :
171
+ self .close ()
172
+
127
173
128
174
class Main (QMainWindow , Ui_MainWindow ):
129
175
def __init__ (self ):
@@ -135,10 +181,17 @@ def __init__(self):
135
181
# style = f"QComboBox::down-arrow {{image: url('{resource_path('resource/arrow.png')}');}}"
136
182
# self.comboBox.setStyleSheet(style)
137
183
# print(style)
184
+
185
+ # 이전 검색 기록 기억
186
+ # 파이썬에선 멤버 변수 선언시 생성자에 적어야함.
187
+ # self를 안적으면 C#이나 Java의 객체 static 선언하고 똑같다고 보면 됨.
188
+ self .prev_item = ""
189
+ self .prev_idx = 0
190
+
138
191
self .show ()
139
192
140
193
def initializer (self ):
141
- self .setTableWidget () # Table Widget Column 폭 Fixed
194
+ self .set_table_widget () # Table Widget Column 폭 Fixed
142
195
self .set_only_int () # 반복횟수는 숫자만 입력할 수 있도록 고정
143
196
self .load_data ('user_save.dat' )
144
197
@@ -177,7 +230,7 @@ def set_only_int(self):
177
230
self .onlyInt = QIntValidator ()
178
231
self .txt_repeat .setValidator (self .onlyInt )
179
232
180
- def setTableWidget (self ):
233
+ def set_table_widget (self ):
181
234
self .articleView .setEditTriggers (
182
235
QAbstractItemView .NoEditTriggers ) # TableWidget 읽기 전용 설정
183
236
self .articleView .setColumnWidth (0 , 60 ) # 글 번호
@@ -188,7 +241,7 @@ def setTableWidget(self):
188
241
self .articleView .setColumnWidth (5 , 40 ) # 조회
189
242
self .articleView .setColumnWidth (6 , 40 ) # 추천
190
243
191
- def setTableAutoSize (self ):
244
+ def set_table_autosize (self ):
192
245
header = self .articleView .horizontalHeader ()
193
246
# 성능을 위해 이제 자동 컬럼조정은 사용하지 않는다.
194
247
# header.setSectionResizeMode(0, QHeaderView.ResizeToContents)
@@ -325,6 +378,58 @@ def on_finished(self):
325
378
thread_dead = True
326
379
pass
327
380
381
+ @ pyqtSlot (str )
382
+ def filtering (self , keyword ):
383
+ # Clear current selection.
384
+ self .articleView .setCurrentItem (None )
385
+
386
+ if not keyword :
387
+ # Empty string, don't search.
388
+ return
389
+
390
+ if self .prev_item == keyword :
391
+ # 같은 키워드가 들어오면 다음 아이템으로 이동해서 확인
392
+ self .prev_idx += 1
393
+ else :
394
+ # 키워드가 달라지면 처음부터 다시 검색
395
+ self .prev_idx = 0
396
+
397
+ matching_items = self .articleView .findItems (keyword , Qt .MatchContains )
398
+ matching_item_cnt = len (matching_items )
399
+ if matching_items :
400
+ # We have found something.
401
+ if self .prev_idx >= matching_item_cnt :
402
+ # 처음부터 다시 검색
403
+ self .prev_idx = 0
404
+ item = matching_items [self .prev_idx ] # Take the first.
405
+ self .prev_item = keyword # 검색한 내용 기억
406
+ self .articleView .setCurrentItem (item )
407
+
408
+ # print(keyword)
409
+
410
+ def keyPressEvent (self , event ):
411
+ # Ctrl + C 누른 경우 Table의 내용 복사
412
+ # https://stackoverflow.com/questions/60715462/how-to-copy-and-paste-multiple-cells-in-qtablewidget-in-pyqt5
413
+ if event .key () == Qt .Key .Key_C and (event .modifiers () & Qt .KeyboardModifier .ControlModifier ):
414
+ copied_cells = sorted (self .articleView .selectedIndexes ())
415
+
416
+ copy_text = ''
417
+ max_column = copied_cells [- 1 ].column ()
418
+ for c in copied_cells :
419
+ copy_text += self .articleView .item (c .row (), c .column ()).text ()
420
+ if c .column () == max_column :
421
+ copy_text += '\n '
422
+ else :
423
+ copy_text += '\t '
424
+
425
+ QApplication .clipboard ().setText (copy_text )
426
+
427
+ # Ctrl + F 누른 경우 검색 창 (필터링 창) 열기
428
+ elif event .key () == Qt .Key .Key_F and (event .modifiers () & Qt .KeyboardModifier .ControlModifier ):
429
+ self .searchWindow = SearchWindow ()
430
+ self .searchWindow .filtering .connect (self .filtering )
431
+ self .searchWindow .show ()
432
+
328
433
329
434
app = QApplication ([])
330
435
main = Main ()
0 commit comments