【问题标题】:Tkinter program not responding in while loopTkinter 程序在 while 循环中没有响应
【发布时间】:2020-06-14 12:56:12
【问题描述】:

我发现了一些关于这个主题的其他问题,但我一个都不明白。

我正在尝试制作一个每 x 分钟发送一条消息的程序,但由于循环中的 time.sleep 程序不再响应。 我尝试了多线程,但它似乎不起作用。我也找到了 root.after 但我认为我不能在 while 循环中使用它。

无论如何,这是我的代码:
(自动碰撞意味着发送 !d 不和谐的碰撞消息)

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time
from time import sleep
import re
import urllib.request
import json
import tkinter as tk
from tkinter import *
import webbrowser
from selenium.webdriver.common.by import By
from tkinter import simpledialog
import threading
from queue import Queue


browser = webdriver.Chrome()
browser.get('https://discord.com/')
driver = browser


# open file
file = open('settings.txt')
all_lines = file.readlines()


def login(emailInput, passwordInput):
    file = open('settings.txt')
    if emailInput == "":
        emailInput = (all_lines[1])
        emailInput = emailInput.replace("\n", "")
    else:
        pass
    if passwordInput == "":
        passwordInput = (all_lines[3])
        passwordInput = passwordInput.replace("\n", "")
    else:
        pass #  If email and password not in entrys => replace by settings.txt credentials else replace settings credentials by entrys
    print(f"Logging in ...({emailInput}:{passwordInput})")
    try: 
        browser.find_element_by_xpath('/html/body/div/div/div/div/header[1]/nav/ul[2]/li[4]/a').click()
        browser.find_element_by_name('email').send_keys(emailInput) # EMAIL
        browser.find_element_by_name('password').send_keys(passwordInput)# PASSWORD
        browser.find_element_by_xpath('/html/body/div/div[2]/div/div[2]/div/div/form/div/div/div[1]/div[3]/div[2]/div/input').send_keys(Keys.ENTER) # CONNNECT
    except:
        print("Error while logging in.\nPlease retry or login manually")


def automsg(cldown):
    if cldown == "":
        cldown = (all_lines[5])
        cldown = cldown.replace("\n", "")
        cldown = int(cldown)
    else:
        pass
    message = (all_lines[7])
    print(message)
    cldown = int(cldown)
    cldown = (cldown * 60)
    while True:
        try:
            chatentry = browser.find_element_by_css_selector(".slateTextArea-1Mkdgw")
            chatentry.send_keys(message)
            chatentry.send_keys(Keys.ENTER)
            print("Message sent successfully !")
        except:
            print("Message failed, trying again ...\n")
            sleep(5)
        print(f"Next message in {cldown} secondes")
        sleep(cldown)


def autobump(cldown):
    if cldown == "":
        cldown = (all_lines[5])
        cldown = cldown.replace("\n", "")
        cldown = int(cldown)
    else:
        pass
    print(cldown)
    cldown = int(cldown)
    cldown = (cldown * 60)
    while True:
        try:
            chatentry = browser.find_element_by_css_selector(".slateTextArea-1Mkdgw")
            chatentry.send_keys("!d bump")
            chatentry.send_keys(Keys.ENTER)
            print("Bumped successfully !")
        except:
            print("Bumped failed, trying again ...\n")
            sleep(5)
        print(f"Next bump in {cldown} secondes")
        sleep(cldown)

def help():
    webbrowser.open('https://pastebin.com/5Vx5qxxx', new=2)



# Looks settings


HEIGHT = 500
WIDTH = 500


root = tk.Tk()
root.title("Discord Assistant (by Sarlay#3151)")
root.minsize(width=WIDTH, height=HEIGHT)
root.maxsize(width=WIDTH, height=HEIGHT)
root.iconbitmap("icon.ico")


canvas = tk.Canvas(root, height=HEIGHT, width=WIDTH)
canvas.pack()


background_image = tk.PhotoImage(file=r"./bg.gif")
background_label = tk.Label(root, image=background_image)
background_label.place(x=0, y=0, relwidth=1, relheight=1)


SettingsFrame = tk.Frame(root, bg="white")
SettingsFrame.place(relx=0.1, rely=0.1, relwidth=0.8, relheight=0.05)

SettingsFrame2 = tk.Frame(root, bg="#24b8b8")
SettingsFrame2.place(relx=0.1, rely=0.15, relwidth=0.8, relheight=0.05)


emailEntry = tk.Entry(SettingsFrame2, font=8)
emailEntry.place(relx=0.02, rely=0.15, relwidth=0.35, relheight=0.8)

emaillabel = tk.Label(SettingsFrame, font=40, text="email")
emaillabel.place(relx=0.15, rely=0.2)

passwordEntry = tk.Entry(SettingsFrame2, font=8)
passwordEntry.place(relx=0.4, rely=0.15, relwidth=0.25, relheight=0.8)

passwordlabel = tk.Label(SettingsFrame, font=40, text="password")
passwordlabel.place(relx=0.44, rely=0.2)

cooldownEntry = tk.Entry(SettingsFrame2, font=8)
cooldownEntry.place(relx=0.67, rely=0.15, relwidth=0.3, relheight=0.8)

cooldownlabel = tk.Label(SettingsFrame, font=8, text="cooldown(min)")
cooldownlabel.place(relx=0.69, rely=0.2)

LoginButton = tk.Button(root, text="Login", font=40, command=lambda: login(emailEntry.get(), passwordEntry.get()))
LoginButton.place(relx=0.46, rely=0.3)

AutoMsgButton = tk.Button(root, text="Auto-message", font=40, command=lambda: automsg(cooldownEntry.get()))
AutoMsgButton.place(relx=0.4, rely=0.4)


HelpButton = tk.Button(root, text="?", font=40, command=help)
HelpButton.place(relx=0.95, rely=0.03)


AutobumpButton = tk.Button(root, text="Auto-Bump", font=40, command=lambda: autobump(cooldownEntry.get()))
AutobumpButton.place(relx=0.42, rely=0.5)

root.mainloop()

【问题讨论】:

  • 事件处理函数需要快速完成,因为在它完成之前,不能处理其他 GUI 事件。睡眠和无限循环都是一个很大的禁忌。请参阅此处:stackoverflow.com/questions/25753632/…,了解如何在不阻塞事件循环的情况下定期发生事情。
  • 您需要使用通用的after() 方法而不是time.sleep() 来在tkinter 应用程序中引入延迟并防止它们“挂起”,因为它的mainloop() 正在受到干扰。

标签: python tkinter


【解决方案1】:

对于这个问题,多线程似乎有点矫枉过正。你可以试试这样的。

import time
send_message()
last_message = time.time() 
while:
    do_stuff()
    if time.time()-last_message > 60*x:  # time.time() - last_message gives the difference in seconds between now and when the last message was send.
        send_new_message()
        last_message = time.time()

【讨论】:

  • 不适用于基于 tkinter 的应用。
猜你喜欢
  • 2016-08-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-16
  • 1970-01-01
  • 2021-09-26
  • 2013-07-18
相关资源
最近更新 更多