@BASARA_heart810

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

入力欄が改行されたままになる

解決したいこと

下記のプログラムでは、入力欄に文章を入力して送信ボタンかエンターキーを押したときに応答文が表示されるようになっているのですが、エンターキーを押下して関数を実行した際に空欄になったinput_box内のマウスカーソルが一文字目ではなくそこから一回改行された位置からスタートしてしまう問題に悩まされています。送信ボタンをクリックして実行した場合は普通に空になったinput_box内のカーソルは一番左上の一文字目からスタートします。どうすればinput_box内のカーソル位置をエンターキーを押して実行したときに左上からスタートさせることができますか?できれば原因も教えていただけると幸いです。

該当するソースコード

import tkinter as tk
from tkinter import scrolledtext
import openai

openai.api_key = "MY_API_KEY"

# 会話の履歴を保存するリスト
conversation_history = []

def get_response():
    user_input = input_box.get("1.0", tk.END).strip()
    input_box.delete("1.0", tk.END)

    # ユーザーの入力を履歴に追加
    conversation_history.append({"role": "user", "content": user_input})

    # OpenAI APIからの返答を取得
    response = openai.ChatCompletion.create(
        model="gpt-3.5-turbo",
        messages=conversation_history,
    )

    response_text = response["choices"][0]["message"]["content"]

    # 返答を履歴に追加
    conversation_history.append({"role": "system", "content": response_text})

    conversation_text.config(state=tk.NORMAL)
    conversation_text.insert(tk.END, f"User: {user_input}\n")
    conversation_text.insert(tk.END, f"AI: {response_text}\n\n")
    conversation_text.config(state=tk.DISABLED)
    conversation_text.see(tk.END)
    
def on_enter_pressed(event):
    # エンターキーが押されたとき、かつShiftキーが押されていない場合のみ処理を実行
    if event.keycode == 13 and not event.state & 0x1:
        get_response()

root = tk.Tk()
root.title("Chat with AI")

# ラベルとエントリーボックスの作成
input_label = tk.Label(root, text="質問を入力してください")
input_label.grid(row=0, column=0)
input_box = scrolledtext.ScrolledText(root, height=5, wrap=tk.WORD)
input_box.bind('<KeyPress>', on_enter_pressed)
input_box.grid(row=1,column=0)

# ボタンの作成
button = tk.Button(root, text="送信", command=get_response)
button.grid(row=2,column=0,sticky=tk.E,padx=10,pady=5)

# やめるボタンの作成
cancel_button = tk.Button(root, text="やめる", command=root.destroy)
cancel_button.grid(row=2, column=1,padx=10,pady=5)

# 会話のテキストウィジェットの作成
conversation_text = tk.Text(root, state=tk.DISABLED)
conversation_text.grid(row=3, column=0, sticky="nsew")

# スクロールバーの作成
scrollbar = tk.Scrollbar(root)
scrollbar.grid(row=3, column=1, sticky="ns")

# スクロールバーの設定
scrollbar.config(command=conversation_text.yview)
conversation_text.config(yscrollcommand=scrollbar.set)

# グリッドの設定
root.rowconfigure(3, weight=1)
root.columnconfigure(0, weight=1)

root.mainloop()
0 likes

2Answer

自己解決しました。
どうやら入力欄でEnterキーを押すと、テキストウィジェットの改行をトリガーしてるっぽくて、それが原因で入力後にカーソルが改行された位置に移動しちゃうらしかったです。
なのでon_enter_pressed関数の最後に、"return 'break'"を追加してイベントが他の処理に続いて伝播しないようにしたらエンターキーによる改行が次の入力欄に影響しないようになりました。
一応下記が追記した内容です。

def on_enter_pressed(event):
    # エンターキーが押されたとき、かつShiftキーが押されていない場合のみ処理を実行
    if event.keycode == 13 and not event.state & 0x1:
        get_response()
        return 'break' # 追記
1Like

しょーもないことですが

input_box内のマウスカーソルが

マウスに合わせて動くあの矢印は本来「マウスポインタ」と呼ぶらしいですが、「マウスカーソル」もかなり昔から使われていてすっかり定着しています。
それと区別するためにテキスト編集位置を示すあの縦棒は「キャレット」と呼んだりします。

今回は「input_box内の~」が前にあったから推測できましたが、文脈によってはマジで混乱して伝わらないこともあり得ます(経験談):sweat_smile:

1Like

Your answer might help someone💌