質問編集履歴
10
修正
title
CHANGED
File without changes
|
body
CHANGED
@@ -282,9 +282,7 @@
|
|
282
282
|
# キューにある先頭データを取り出す
|
283
283
|
msg, args = data.get()
|
284
284
|
print(msg, args)
|
285
|
-
if msg == "DB-CNCT":
|
286
|
-
cnct()
|
287
|
-
|
285
|
+
if msg == "DB-INSERT":
|
288
286
|
# データベースとの接続がタイムアウトしていたときのための再接続。
|
289
287
|
con.ping(reconnect=True)
|
290
288
|
# tmpにあるデータをデータベースに保存
|
9
修正
title
CHANGED
File without changes
|
body
CHANGED
@@ -205,7 +205,7 @@
|
|
205
205
|
con.commit()
|
206
206
|
```
|
207
207
|
|
208
|
-
# 質問後追記 変更(2020/10/08 14:
|
208
|
+
# 質問後追記 変更(2020/10/08 14:39)
|
209
209
|
```Python:
|
210
210
|
from datetime import datetime
|
211
211
|
import csv
|
@@ -298,7 +298,7 @@
|
|
298
298
|
elif msg == "DB-COMMIT":
|
299
299
|
con.commit()
|
300
300
|
elif msg == "DB-DISCNCT":
|
301
|
-
|
301
|
+
break
|
302
302
|
else:
|
303
303
|
break
|
304
304
|
discnct(con, cur)
|
8
修正
title
CHANGED
File without changes
|
body
CHANGED
@@ -205,7 +205,7 @@
|
|
205
205
|
con.commit()
|
206
206
|
```
|
207
207
|
|
208
|
-
# 質問後追記 変更(2020/10/08 14:
|
208
|
+
# 質問後追記 変更(2020/10/08 14:37)
|
209
209
|
```Python:
|
210
210
|
from datetime import datetime
|
211
211
|
import csv
|
@@ -300,8 +300,8 @@
|
|
300
300
|
elif msg == "DB-DISCNCT":
|
301
301
|
discnct(con, cur)
|
302
302
|
else:
|
303
|
+
break
|
303
|
-
|
304
|
+
discnct(con, cur)
|
304
|
-
break
|
305
305
|
|
306
306
|
|
307
307
|
def close():
|
7
修正
title
CHANGED
File without changes
|
body
CHANGED
@@ -300,7 +300,7 @@
|
|
300
300
|
elif msg == "DB-DISCNCT":
|
301
301
|
discnct(con, cur)
|
302
302
|
else:
|
303
|
-
|
303
|
+
discnct(con, cur)
|
304
304
|
break
|
305
305
|
|
306
306
|
|
6
修正
title
CHANGED
File without changes
|
body
CHANGED
@@ -223,7 +223,7 @@
|
|
223
223
|
con = pymysql.connect(
|
224
224
|
host = "localhost",
|
225
225
|
user = "root",
|
226
|
-
password = "
|
226
|
+
password = "root",
|
227
227
|
db = "testdb",
|
228
228
|
charset = "utf8"
|
229
229
|
)
|
5
修正
title
CHANGED
File without changes
|
body
CHANGED
@@ -205,7 +205,7 @@
|
|
205
205
|
con.commit()
|
206
206
|
```
|
207
207
|
|
208
|
-
# 質問後追記 変更(2020/10/08
|
208
|
+
# 質問後追記 変更(2020/10/08 14:34)
|
209
209
|
```Python:
|
210
210
|
from datetime import datetime
|
211
211
|
import csv
|
@@ -223,7 +223,7 @@
|
|
223
223
|
con = pymysql.connect(
|
224
224
|
host = "localhost",
|
225
225
|
user = "root",
|
226
|
-
password = "
|
226
|
+
password = "sh1n@n0pisql",
|
227
227
|
db = "testdb",
|
228
228
|
charset = "utf8"
|
229
229
|
)
|
@@ -281,6 +281,7 @@
|
|
281
281
|
while True:
|
282
282
|
# キューにある先頭データを取り出す
|
283
283
|
msg, args = data.get()
|
284
|
+
print(msg, args)
|
284
285
|
if msg == "DB-CNCT":
|
285
286
|
cnct()
|
286
287
|
elif msg == "DB-INSERT":
|
@@ -299,8 +300,8 @@
|
|
299
300
|
elif msg == "DB-DISCNCT":
|
300
301
|
discnct(con, cur)
|
301
302
|
else:
|
303
|
+
discnct(con, cur)
|
302
304
|
break
|
303
|
-
time.sleep(0.1)
|
304
305
|
|
305
306
|
|
306
307
|
def close():
|
4
修正
title
CHANGED
File without changes
|
body
CHANGED
@@ -205,20 +205,20 @@
|
|
205
205
|
con.commit()
|
206
206
|
```
|
207
207
|
|
208
|
-
# 質問後追記
|
208
|
+
# 質問後追記 変更(2020/10/08 12:58)
|
209
209
|
```Python:
|
210
210
|
from datetime import datetime
|
211
211
|
import csv
|
212
212
|
import pymysql
|
213
213
|
import queue
|
214
214
|
import threading
|
215
|
+
import time
|
215
216
|
import tkinter as tk
|
216
217
|
|
217
218
|
tbl = "testtb"
|
218
219
|
tmp = []
|
219
220
|
|
220
221
|
def cnct():
|
221
|
-
global con, cur
|
222
222
|
# データベース接続
|
223
223
|
con = pymysql.connect(
|
224
224
|
host = "localhost",
|
@@ -229,16 +229,17 @@
|
|
229
229
|
)
|
230
230
|
cur = con.cursor()
|
231
231
|
|
232
|
+
return con, cur
|
232
233
|
|
234
|
+
|
233
|
-
def discnct():
|
235
|
+
def discnct(con, cur):
|
234
|
-
global con, cur
|
235
236
|
# データベース切断
|
236
237
|
cur.close()
|
237
238
|
con.close()
|
238
239
|
|
239
240
|
|
240
|
-
def read_and_csvout():
|
241
|
+
def read_and_csvout(cur):
|
241
|
-
global
|
242
|
+
global tbl
|
242
243
|
cur.execute("SELECT * FROM " + tbl + ";")
|
243
244
|
results = cur.fetchall()
|
244
245
|
lst = []
|
@@ -251,8 +252,8 @@
|
|
251
252
|
writer.writerow(lst[i])
|
252
253
|
|
253
254
|
|
254
|
-
def clear():
|
255
|
+
def clear(cur):
|
255
|
-
global
|
256
|
+
global tbl
|
256
257
|
cur.execute("DELETE FROM " + tbl + ";")
|
257
258
|
|
258
259
|
|
@@ -275,34 +276,31 @@
|
|
275
276
|
|
276
277
|
|
277
278
|
def loop(data):
|
279
|
+
con, cur = cnct()
|
278
280
|
# キュー監視ループ
|
279
281
|
while True:
|
280
|
-
# キューにデータが存在したら、順番通りにデータベースへ保存する
|
281
|
-
while not data.empty():
|
282
|
-
|
282
|
+
# キューにある先頭データを取り出す
|
283
|
-
|
283
|
+
msg, args = data.get()
|
284
|
-
|
284
|
+
if msg == "DB-CNCT":
|
285
|
-
|
285
|
+
cnct()
|
286
|
-
|
286
|
+
elif msg == "DB-INSERT":
|
287
|
-
global cur, con
|
288
|
-
|
287
|
+
# データベースとの接続がタイムアウトしていたときのための再接続。
|
289
|
-
|
288
|
+
con.ping(reconnect=True)
|
290
|
-
|
289
|
+
# tmpにあるデータをデータベースに保存
|
291
|
-
|
290
|
+
cur.execute("INSERT INTO " + tbl + " VALUES(%s,%s,%s);", (args[0], args[1], args[2]))
|
292
|
-
|
291
|
+
elif msg == "CSV-OUTPUT":
|
293
|
-
global cur, con
|
294
|
-
|
292
|
+
# データベースとの接続がタイムアウトしていたときのための再接続。
|
295
|
-
|
293
|
+
con.ping(reconnect=True)
|
296
|
-
|
294
|
+
read_and_csvout(cur)
|
297
|
-
|
295
|
+
clear(cur)
|
298
|
-
|
296
|
+
con.commit()
|
299
|
-
|
297
|
+
elif msg == "DB-COMMIT":
|
300
|
-
global con
|
301
|
-
|
298
|
+
con.commit()
|
302
|
-
|
299
|
+
elif msg == "DB-DISCNCT":
|
303
|
-
|
300
|
+
discnct(con, cur)
|
304
|
-
|
301
|
+
else:
|
305
|
-
|
302
|
+
break
|
303
|
+
time.sleep(0.1)
|
306
304
|
|
307
305
|
|
308
306
|
def close():
|
@@ -332,8 +330,6 @@
|
|
332
330
|
thread = threading.Thread(target=loop, args=(data, ))
|
333
331
|
thread.start()
|
334
332
|
|
335
|
-
data.put(("DB-CNCT", None))
|
336
|
-
|
337
333
|
# ボタンバインド
|
338
334
|
button1.bind("<ButtonRelease>", pushed1)
|
339
335
|
button2.bind("<ButtonRelease>", pushed2)
|
3
追加
title
CHANGED
File without changes
|
body
CHANGED
@@ -203,4 +203,158 @@
|
|
203
203
|
データベースクリア()
|
204
204
|
# コミット。データベースに変更を加えたらそれを反映させるために必要。
|
205
205
|
con.commit()
|
206
|
+
```
|
207
|
+
|
208
|
+
# 質問後追記
|
209
|
+
```Python:
|
210
|
+
from datetime import datetime
|
211
|
+
import csv
|
212
|
+
import pymysql
|
213
|
+
import queue
|
214
|
+
import threading
|
215
|
+
import tkinter as tk
|
216
|
+
|
217
|
+
tbl = "testtb"
|
218
|
+
tmp = []
|
219
|
+
|
220
|
+
def cnct():
|
221
|
+
global con, cur
|
222
|
+
# データベース接続
|
223
|
+
con = pymysql.connect(
|
224
|
+
host = "localhost",
|
225
|
+
user = "root",
|
226
|
+
password = "root",
|
227
|
+
db = "testdb",
|
228
|
+
charset = "utf8"
|
229
|
+
)
|
230
|
+
cur = con.cursor()
|
231
|
+
|
232
|
+
|
233
|
+
def discnct():
|
234
|
+
global con, cur
|
235
|
+
# データベース切断
|
236
|
+
cur.close()
|
237
|
+
con.close()
|
238
|
+
|
239
|
+
|
240
|
+
def read_and_csvout():
|
241
|
+
global cur, tbl
|
242
|
+
cur.execute("SELECT * FROM " + tbl + ";")
|
243
|
+
results = cur.fetchall()
|
244
|
+
lst = []
|
245
|
+
for i in range(len(results)):
|
246
|
+
tmp = results[i]
|
247
|
+
lst.append([ tmp[0], tmp[1], tmp[2] ])
|
248
|
+
with open("/home/pi/デスクトップ/data.csv", "a", newline="") as f:
|
249
|
+
writer = csv.writer(f, lineterminator="\r\n")
|
250
|
+
for i in range(len(lst)):
|
251
|
+
writer.writerow(lst[i])
|
252
|
+
|
253
|
+
|
254
|
+
def clear():
|
255
|
+
global cur, tbl
|
256
|
+
cur.execute("DELETE FROM " + tbl + ";")
|
257
|
+
|
258
|
+
|
259
|
+
def pushed1(e):
|
260
|
+
global data
|
261
|
+
# データベース保存用データをキューに格納
|
262
|
+
for i in range(50):
|
263
|
+
data.put(("DB-INSERT", [str(i+1), "ButtonPushed1", ""]))
|
264
|
+
data.put(("DB-COMMIT", None))
|
265
|
+
|
266
|
+
|
267
|
+
def pushed2(e):
|
268
|
+
global data
|
269
|
+
# データベース保存用データをキューに格納
|
270
|
+
for i in range(50):
|
271
|
+
data.put(("DB-INSERT", [str(i+1), "ButtonPushed2", ""]))
|
272
|
+
data.put(("DB-COMMIT", None))
|
273
|
+
data.put(("CSV-OUTPUT", None))
|
274
|
+
|
275
|
+
|
276
|
+
|
277
|
+
def loop(data):
|
278
|
+
# キュー監視ループ
|
279
|
+
while True:
|
280
|
+
# キューにデータが存在したら、順番通りにデータベースへ保存する
|
281
|
+
while not data.empty():
|
282
|
+
# キューにある先頭データを取り出す
|
283
|
+
msg, args = data.get()
|
284
|
+
if msg == "DB-CNCT":
|
285
|
+
cnct()
|
286
|
+
elif msg == "DB-INSERT":
|
287
|
+
global cur, con
|
288
|
+
# データベースとの接続がタイムアウトしていたときのための再接続。
|
289
|
+
con.ping(reconnect=True)
|
290
|
+
# tmpにあるデータをデータベースに保存
|
291
|
+
cur.execute("INSERT INTO " + tbl + " VALUES(%s,%s,%s);", (args[0], args[1], args[2]))
|
292
|
+
elif msg == "CSV-OUTPUT":
|
293
|
+
global cur, con
|
294
|
+
# データベースとの接続がタイムアウトしていたときのための再接続。
|
295
|
+
con.ping(reconnect=True)
|
296
|
+
read_and_csvout()
|
297
|
+
clear()
|
298
|
+
con.commit()
|
299
|
+
elif msg == "DB-COMMIT":
|
300
|
+
global con
|
301
|
+
con.commit()
|
302
|
+
elif msg == "DB-DISCNCT":
|
303
|
+
discnct()
|
304
|
+
else:
|
305
|
+
break
|
306
|
+
|
307
|
+
|
308
|
+
def close():
|
309
|
+
global data, win, thread
|
310
|
+
data.put(("DB-DISCNCT", None))
|
311
|
+
thread.join()
|
312
|
+
# Tkinterアプリの終了
|
313
|
+
win.destroy()
|
314
|
+
|
315
|
+
|
316
|
+
if __name__ == "__main__":
|
317
|
+
|
318
|
+
# データベースに保存するデータ格納用
|
319
|
+
data = queue.Queue()
|
320
|
+
|
321
|
+
# Tkinter UI
|
322
|
+
win = tk.Tk()
|
323
|
+
|
324
|
+
# ボタン
|
325
|
+
button1 = tk.Button(win, text="Button1")
|
326
|
+
button1.grid(row=0, column=0, sticky="nsew")
|
327
|
+
button2 = tk.Button(win, text="Button2")
|
328
|
+
button2.grid(row=0, column=1, sticky="nsew")
|
329
|
+
|
330
|
+
# データベース操作スレッド
|
331
|
+
# ※データベース操作はスレッドセーフではないため、1つのスレッドでのみ操作が可能
|
332
|
+
thread = threading.Thread(target=loop, args=(data, ))
|
333
|
+
thread.start()
|
334
|
+
|
335
|
+
data.put(("DB-CNCT", None))
|
336
|
+
|
337
|
+
# ボタンバインド
|
338
|
+
button1.bind("<ButtonRelease>", pushed1)
|
339
|
+
button2.bind("<ButtonRelease>", pushed2)
|
340
|
+
|
341
|
+
# UIクローズ検知
|
342
|
+
win.protocol("WM_DELETE_WINDOW", close)
|
343
|
+
|
344
|
+
# イベントループ
|
345
|
+
win.mainloop()
|
346
|
+
|
347
|
+
|
348
|
+
"""
|
349
|
+
MariaDB [testdb]> DESC testtb;
|
350
|
+
+-------+------+------+-----+---------+-------+
|
351
|
+
| Field | Type | Null | Key | Default | Extra |
|
352
|
+
+-------+------+------+-----+---------+-------+
|
353
|
+
| data1 | text | YES | | NULL | |
|
354
|
+
| data2 | text | YES | | NULL | |
|
355
|
+
| data3 | text | YES | | NULL | |
|
356
|
+
+-------+------+------+-----+---------+-------+
|
357
|
+
3 rows in set (0.00 sec)
|
358
|
+
"""
|
359
|
+
|
206
360
|
```
|
2
修正
title
CHANGED
File without changes
|
body
CHANGED
@@ -30,7 +30,7 @@
|
|
30
30
|
con = pymysql.connect(
|
31
31
|
host = "localhost",
|
32
32
|
user = "root",
|
33
|
-
password = "
|
33
|
+
password = "root",
|
34
34
|
db = "testdb",
|
35
35
|
charset = "utf8"
|
36
36
|
)
|
1
追加
title
CHANGED
File without changes
|
body
CHANGED
@@ -177,6 +177,8 @@
|
|
177
177
|
|
178
178
|
このときにButton2を押したときの処理が、メインスレッドだとバッファにキューに保存しているだけなのでMySQL操作しているスレッドの動作まで検知できません。
|
179
179
|
|
180
|
+
(グローバル変数で適当なフラグを立てることを考えたのですが、Button1のデータ書き込みが終わったのか、Button2のデータ書き込みが終わったのか、そもそも書き込んでいないのかまではloop()内で区別できないような気がします。変数だけじゃなくコールバック関数などを駆使すればできる?)
|
181
|
+
|
180
182
|
どのようにすれば 50,ButtonPushed2 をデータベースに保存した後でCSV出力をすることが可能でしょうか。
|
181
183
|
|
182
184
|
(ただし、出力データ 50,ButtonPushed2 はあくまでサンプルデータにすぎないので、実際に保存するデータはどうなるか分かりません。そのためスレッドのループ内に下記のような指定をするのはなしでお願いします。)
|
@@ -194,7 +196,7 @@
|
|
194
196
|
tmp = data.get()
|
195
197
|
# tmpにあるデータをデータベースに保存
|
196
198
|
cur.execute("INSERT INTO " + tbl + " VALUES(%s,%s,%s);", (tmp[0], tmp[1], tmp[2]))
|
197
|
-
# データの内容を指定して、CSV出力
|
199
|
+
# データの内容を指定して、CSV出力(これは解決策としては×)
|
198
200
|
if tmp == ["50", "ButtonPushed2", ""]:
|
199
201
|
sqldata = データベース読み込み()
|
200
202
|
CSV出力(sqldata)
|