# coding: UTF-8

import tkinter as tk
import tkinter.scrolledtext as st
import tkinter.ttk as ttk
import threading
import myvisa


# NI VISAクラスのインスタンス化
visa = None

# メインウィンドウ
root = tk.Tk()
root.title( 'Sample')
root.resizable( 0, 0)

#フレームの生成
frame1 = tk.Frame(root)
frame2 = tk.Frame(root)
frame3 = tk.Frame(root)
frame4 = tk.Frame(root)

# VISAアドレス
label1 = tk.Label( frame1, text='VISAアドレス', anchor = tk.E, width = 10)
label1.pack( side = tk.LEFT)

resource = tk.StringVar()
combobox1 = ttk.Combobox( frame1, textvariable = resource, width = 27)
combobox1.pack( side = tk.LEFT)

# 「検出」ボタンを押したときの処理
def button1_Click():
    combobox1.config(state = "disable")
    button1.config(state = "disable")
    button2.config(state = "disable")
    resource.set("Searching For Resources ...")
    t = threading.Thread(target=resourceThread)
    t.start()

def resourceThread():
    global visa
    visa = myvisa.Myvisa()
    if len(visa.get_resources()) > 0:
        combobox1.config(value = visa.get_resources())
        combobox1.current(0)
    else:
        resource.set("")
    visa.close()
    combobox1.config(state = "active")
    button1.config(state = "active")
    button2.config(state = "active")

button1 = tk.Button(frame1, text='検出', width = 10, command = button1_Click)
button1.pack( side = tk.LEFT, padx = 5)


# 「接続」ボタンを押したときの処理
def button2_Click():
    global visa
    visa = myvisa.Myvisa()
    # 接続
    if not visa.open(resource.get()):
        return

    # ボタンとテキストボックスの有効/無効の処理
    combobox1.config(state = "disable")
    button1.config(state = "disable")
    button2.config(state = "disable")
    button3.config(state = "active")
    button4.config(state = "active")

button2 = tk.Button(frame1, text='接続', width = 10, command = button2_Click)
button2.pack( side = tk.LEFT, padx = 5)


# 「切断」ボタンを押したときの処理
def button3_Click():
    # 切断
    global visa
    visa.close()

    # ボタンとテキストボックスの有効/無効の処理
    combobox1.config(state = "active")
    button1.config(state = "active")
    button2.config(state = "active")
    button3.config(state = "disable")
    button4.config(state = "disable")

button3 = tk.Button(frame1, text='切断', width = 10, command = button3_Click)
button3.config(state = "disable")
button3.pack( side = tk.LEFT, padx = 5)


# コマンド
label2 = tk.Label( frame2, text='コマンド', anchor = tk.E, width = 10)
label2.pack( side = tk.LEFT)

command = tk.StringVar()
command.set("*IDN?")
textbox2 = tk.Entry( frame2, textvariable = command, width = 30)
textbox2.pack( side = tk.LEFT)

# 「送受信」ボタンを押したときの処理
def button4_Click():
    global visa
    button4.config(state = "disable")

    textbox4.insert(tk.INSERT, "<< " + command.get() + "\n")          # 送信データログ出力
    visa.send_query_msg(command.get(), int(timeout.get()) * 1000)     # 送受信

    if "?" in command.get() :                                         # コマンドに?が含まれる場合
        textbox4.insert(tk.INSERT, ">> " + visa.msg_buf + "\n")       # 受信データログ出力

    button4.config(state = "active")


button4 = tk.Button(frame2, text='送受信', width = 10, command = button4_Click)
button4.config(state = "disable")
button4.pack( side = tk.LEFT, padx = 5)


#「タイムアウト」
label3 = tk.Label( frame3, text='タイムアウト', anchor = tk.E, width = 10)
label3.pack( side = tk.LEFT)

timeout = tk.StringVar()
timeout.set("1")
textbox3 = tk.Entry( frame3, textvariable = timeout, width = 10)
textbox3.pack( side = tk.LEFT)

label4 = tk.Label( frame3, text='秒', anchor = tk.E)
label4.pack( side = tk.LEFT)


# ログ
def ctrlEvent(event):
    if(12 == event.state and event.keysym=='c' ):   # Ctrl + C キーのみ有効
        return
    else:
        return "break"                              # それ以外のキー入力は無効

textbox4 = st.ScrolledText( frame4, width = 60, height = 20)
textbox4.bind("<Key>", lambda e: ctrlEvent(e))      # キーバインド
textbox4.pack( side = tk.LEFT)


# 「クリア」ボタンを押したときの処理
def button5_Click():
    textbox4.delete('1.0', 'end')

button5 = tk.Button(frame4, text='クリア', width = 10, command = button5_Click)
button5.pack( side = tk.TOP, padx = 5)

# フレームの配置
frame1.pack(anchor = tk.NW, padx = 20, pady = 10)
frame2.pack(anchor = tk.NW, padx = 20, pady = 10)
frame3.pack(anchor = tk.NW, padx = 20, pady = 10)
frame4.pack(anchor = tk.NW, padx = 20, pady = 10)


root.update() # 画面更新

root.geometry( str(frame1.winfo_width() + 50) + 'x430')  # ウィンドウサイズ変更

# 画面をそのまま表示
root.mainloop()
