2301_79951294 2023-09-24 22:41 采纳率: 0%
浏览 23
已结题

这段代码可以正常运行,打包后无法执行,在执行for内容之前一直不断弹窗,请修改调整


from turtle import pd
import pyscreenshot as ImageGrab
import pytesseract
import pygetwindow as gw
import pyautogui
import time
import pandas
import pyperclip
import openpyxl
import tkinter as tk
from tkinter import messagebox
import psutil
import pygetwindow as gw

# 创建主窗口
root = tk.Tk()
root.withdraw()  # 隐藏主窗口,只显示对话框

# 创建进度窗口的函数
def create_progress_window():
    progress_window = tk.Toplevel()
    progress_window.title("程序进行中,请不要执行其他操作")
    progress_window.geometry("800x400")
    progress_window.attributes("-alpha", 0.7)
    progress_window.wm_attributes("-topmost", 1)  # 设置窗口始终置顶

    # 创建文本框用于显示进度和打印结果
    progress_text = tk.Text(progress_window)
    progress_text.pack(fill="both", expand=True)

    # 将窗口放置在左下角
    screen_width = progress_window.winfo_screenwidth()
    screen_height = progress_window.winfo_screenheight()
    progress_window.geometry("600x400+{}+{}".format(0, screen_height - 400))

    return progress_window, progress_text

# 隐藏进度窗口的函数
def hide_progress_window(progress_window):
    progress_window.withdraw()

# 显示进度窗口的函数
def show_progress_window(progress_window):
    progress_window.deiconify()

# 更新进度文本的函数
def update_progress_text(progress_text, text):
    progress_text.insert(tk.END, text + "\n")  # 在文本框中插入新文本
    progress_text.see(tk.END)  # 滚动文本框以查看新插入的文本
    progress_text.update_idletasks()  # 强制刷新界面

# 创建进度窗口
progress_window, progress_text = create_progress_window()

# 显示确认对话框
user_response = messagebox.askquestion("确认执行程序", "你正在执行自动下单程序,请打开EAS采购申请单序时簿,程序执行期间避免其他操作,你准备好了吗?")

# 根据用户的选择执行相应的操作
if user_response == "yes":
    # 执行程序的主要逻辑
    # 在这里放置你的程序代码
    update_progress_text(progress_text, "用户已确认,执行程序...")
    print("用户已确认,执行程序...")

    # 打开 Excel 文件,获取执行次数的数值
    workbook = openpyxl.load_workbook('基础表_执行次数.xlsx')
    sheet = workbook.active
    b1_value = int(sheet['B1'].value)
    x1_value = int(sheet['B2'].value)
    y1_value = int(sheet['C2'].value)
    x2_value = int(sheet['D2'].value)
    y2_value = int(sheet['E2'].value)
    xx1_value = int(sheet['B3'].value)
    yy1_value = int(sheet['C3'].value)
    xx2_value = int(sheet['D3'].value)
    yy2_value = int(sheet['E3'].value)

    contact_file_path = "基础表_坐标.xlsx"  # 从Excel文件中读取基础表_坐标数据
    contacts_df = pandas.read_excel(contact_file_path)  
    material_file_path = "基础表_物料.xlsx" # 从Excel文件中读取基础表_物料数据
    material_df = pandas.read_excel(material_file_path,dtype={'物料编码': str})

    # 四个坐标点的值
    x1, y1 = x1_value, y1_value
    x2, y2 = x2_value, y2_value
    y_offset = 20# 定义坐标增加的偏移量
    
    # 定义一个计数器
    consecutive_same_result_count = 0
    max_consecutive_same_result_count = 20  # 或者 30,根据你的需求调整
    previous_result = None  # 用于存储上一次的 OCR 识别结果
    
    # 定义一个点击行的函数
    def click_row_by_value(df, column_name, target_value):
        row = df[df[column_name] == target_value]
        if not row.empty:
            x_click = row.iloc[0]['X坐标']
            y_click = row.iloc[0]['Y坐标']
            wait_time = row.iloc[0]['等待时间'] if '等待时间' in df.columns else 2  # 获取等待时间,如果列不存在,默认为2秒
            pyautogui.click(x=x_click, y=y_click)
            #print(f"点击坐标:({x_click}, {y_click})")
            #添加等待时间
            time.sleep(wait_time)
        else:
            update_progress_text(progress_text, f"未找到名称为'{target_value}'的行")
            print(f"未找到名称为'{target_value}'的行")

    # 定义复制数据的函数
    def copy_to_clipboard_and_paste(text,field_name):
        # 清理OCR识别结果和物料表中的物料编码,移除多余的空格和换行符
        ocr_result_cleaned = text.strip()  # 移除开头和结尾的空格和换行符
        material_df['物料编码'] = material_df['物料编码'].str.strip()  # 移除物料表中物料编码列的空格和换行符
        datacontent = material_df.loc[material_df['物料编码'] == ocr_result_cleaned, field_name].values[0]
        pyperclip.copy(datacontent)    # 将供应商的值复制到剪贴板
        time.sleep(0.25)    # 等待一段时间(例如2秒)
        pyautogui.hotkey('ctrl', 'v')    # 模拟按下Ctrl+V组合键来粘贴
        time.sleep(0.25)  # 等待一段时间(例如2秒)
        pyautogui.press('enter')  # 模拟按下回车键
    
    # 定义一个获取窗口标题的函数
    def get_window_titles(stop_char=None):
        while True:
            # 获取所有打开的窗口的标题
            window_list = gw.getAllTitles()
            # 打印窗口标题
            for window_title in window_list:
                #print(window_title)
                # 检查是否出现了指定的停止字符
                if stop_char and stop_char in window_title:
                    return  # 如果出现指定字符,停止函数执行
            time.sleep(1)# 等待一秒钟

    # 定义OCR循环识别函数
    def dynamic_ocr(stop_text):
        while True:
            
            screenshot = ImageGrab.grab(bbox=(xx1_value, yy1_value, xx2_value, yy2_value))# 获取屏幕截图         
            text = pytesseract.image_to_string(screenshot, lang='chi_sim')# 进行OCR识别
            #print("识别结果:", text)           
            if stop_text in text: # 检查是否包含停止字符
                break  # 如果出现停止字符,终止循环
            time.sleep(0.5)# 等待一段时间再进行下一次识别
                    # 添加检查是否出现"提交"的条件

    #定义执行自动下单案件模拟函数
    def process_order_from_ocr(x1, y1, x2, y2, material_df, contacts_df):
        screenshot = ImageGrab.grab(bbox=(x1, y1, x2, y2))# 获取屏幕截图
        text = pytesseract.image_to_string(screenshot)# 进行OCR识别
        
        # 检查OCR识别结果是否为空
        if not text:
            update_progress_text(progress_text, f"OCR未识别到信息,请确认。继续请输入 'y',退出请输入回车:")
            user_input = input("OCR未识别到信息,请确认。继续请输入 'y',退出请输入回车:")
            if user_input.lower() != 'y':
                return

        invalid_supplier = None  # 用于存储无效供应商的变量
        material_code = text.strip()  # 移除开头和结尾的空格和换行符
        material_code_count = material_df['物料编码'].value_counts().get(material_code, 0) # 检查匹配的物料编码在Excel中出现的次数

        #检查OCR识别结果是否在Excel文件的物料编码列中
        if text.strip() in material_df['物料编码'].values:

            # 如果匹配到的物料编码在Excel中出现了两次及以上,跳过处理
            if material_code_count >= 2:
                update_progress_text(progress_text, f"该物料编码存在多条信息: {material_code}")
                print(f"该物料编码存在多条信息: {material_code}")
                return

            x_click = x1 + 50 # 1. 点击物料编码所在的行
            y_click = y1 + 12
            pyautogui.click(x=x_click, y=y_click) 
            update_progress_text(progress_text, f"正在生成订单:{text}")
            print(f"正在生成订单:{text}",end='')

            # 创建要点击的目标值列表
            target_values = ["关联生成", "确认关联生成", "供应商", "输入供应商"]# 创建要点击的目标值列表
            for target_value in target_values: # 遍历目标值列表,并依次调用函数
                click_row_by_value(contacts_df, '击点名称', target_value)
                if target_value == "关联生成":
                    get_window_titles(stop_char="单据转换")# 调用函数,并在出现指定字符时停止
                    # 添加延时/秒
                    time.sleep(0.5)
                elif target_value == "确认关联生成":
                    get_window_titles(stop_char="采购订单")# 调用函数,并在出现指定字符时停止
                    # 添加延时/秒
                    time.sleep(1.5)     
                elif target_value == "供应商":
                    get_window_titles(stop_char="供应商")# 调用函数,并在出现指定字符时停止
                    # 添加延时/秒
                    time.sleep(1)
                elif target_value == "输入供应商":
                    copy_to_clipboard_and_paste(text, '供应商')# 使用示例,传递字段名称作为参数
                    time.sleep(1)

            target_values = ["确认供应商" ,"币别", "人民币", "确认人民币", "辅助属性", "辅助属性1","输入辅助属性" ]# 创建要点击的目标值列表
            for target_value in target_values:# 遍历目标值列表,并依次调用函数
                click_row_by_value(contacts_df, '击点名称', target_value)
                if target_value == "币别":
                    get_window_titles(stop_char="币别")# 调用函数,并在出现指定字符时停止
                    # 添加延时/秒
                    time.sleep(1)
                elif target_value == "辅助属性1":
                    get_window_titles(stop_char="辅助属性F7查询")# 调用函数,并在出现指定字符时停止
                    # 添加延时/秒
                    time.sleep(1)
                elif target_value == "输入辅助属性":
                    # 添加延时/秒
                    copy_to_clipboard_and_paste(text, '辅助属性')# 使用示例,传递字段名称作为参数
                    time.sleep(1)

            # 创建要点击的目标值列表
            target_values = ["确认辅助属性" , "提交订单", "关闭订单界面"]
            # 遍历目标值列表,并依次调用函数
            for target_value in target_values:
                click_row_by_value(contacts_df, '击点名称', target_value)
                if target_value == "确认辅助属性":                    
                    time.sleep(1) 
                elif target_value == "提交订单":
                    # 添加延时/秒
                    time.sleep(0.5) 
                    dynamic_ocr(stop_text="提")
          
        else:
            invalid_supplier = text.strip()  # 存储无效供应商的文本
        if invalid_supplier:
            update_progress_text(progress_text, f"OCR识别结果中无有效供应商: {invalid_supplier}")
            print(f"OCR识别结果中无有效供应商: {invalid_supplier}")

    #主程序开始执行
    update_progress_text(progress_text, "执行FOR函数")
    print("执行FOR函数")
    for _ in range(b1_value-1):  # 这里的2表示执行两次,您可以根据需要更改次数
        process_order_from_ocr(x1, y1, x2, y2, material_df, contacts_df)
                
        # 增加坐标的y值偏移量,以便下次操作
        y1 += y_offset
        y2 += y_offset

    update_progress_text(progress_text, "执行while函数")
    print("执行while函数")
    while consecutive_same_result_count < max_consecutive_same_result_count:
        result = process_order_from_ocr(x1, y1, x2, y2, material_df, contacts_df)
        click_row_by_value(contacts_df, '击点名称',"申请单序时簿点击↓" )
        # 检查 OCR 识别结果是否与上一次相同
        if result == previous_result:
            consecutive_same_result_count += 1
        else:
            consecutive_same_result_count = 0  # 重置计数器
            previous_result = result
    # 在这里可以添加代码来结束执行或者执行其他操作

    update_progress_text(progress_text, "达到最大连续相同结果次数,结束执行")
    print("达到最大连续相同结果次数,结束执行")

else:
    update_progress_text(progress_text, "用户取消了程序执行")
    print("用户取消了程序执行")

# 关闭主窗口
root.destroy()

```****

```

  • 写回答

4条回答 默认 最新

  • Edge_Coduck_S07738 2023-09-25 09:00
    关注

    根据您的描述,可能是因为程序在执行时弹出了对话框,但是打包后没有处理好对话框的显示,导致程序无法继续执行。

    您可以将程序中所有的对话框的调用代码全部注释掉,或者添加一个参数来控制是否显示对话框。另外,您可以尝试使用PyInstaller或者其他打包工具来重新打包程序,并按照打包工具的说明进行配置,这样可以确保程序在打包后能够正常执行。

    评论
  • 数据大魔王 2023-09-25 10:18
    关注

    根据你的描述,代码在执行for循环时会弹出窗口。这可能是因为自动化操作与GUI操作发生了冲突,导致窗口弹出或者焦点切换不正确。

    你可以考虑以下几种方式:

    分离自动化和GUI操作:将自动化脚本和GUI操作分开执行。首先运行自动化脚本,完成后再弹出 GUI 窗口。

    使用定时器或者事件触发:在自动化操作之前,等待一段时间,或者等待某个事件触发后再执行自动化操作,以确保 GUI 操作不会干扰到自动化操作。

    使用虚拟机或者容器:将自动化脚本运行在一个独立的虚拟机或者容器中,以隔离自动化操作和 GUI 操作的影响。

    禁用 GUI 提示框:在自动化执行期间,通过设置 GUI 库的配置,禁用任何弹出的提示框,以防止干扰自动化操作。

    评论
  • coder_small_bell 2023-09-25 19:56
    关注

    加个exit()看一下

    评论
  • 专家-赤兔[在线] 2023-09-24 22:46
    关注

    此回复引用 皆我百晓生 小程序,希望对题主有所帮助,如有帮助,还请采纳。


    根据您提供的代码,我检查了一下,并且发现了些问题。

    首先,代码中有两个import pygetwindow gw的语句,您可以删除其中一个。

    其次,在执行for循环之前一直弹出窗口的问题可能是因为代码中没有包含执行次数b1_value的赋值语句。您可以检查一下'基础表_执行次数.xlsx'文件中单元格B1是否包含了正确的执行次数。

    此外,代码中还有一些tkinter窗口相关的代码,可能是导致无法打包执行的原因。如果您需要打包代码运行而不弹出窗口,可以考虑将与窗口相关的代码注释掉或者修改为在控制台打印信息。

    最后,请注意代码中的路径和文件名是否正确,以及是否缺少相关的依赖库。如果缺少依赖库,可以使用pip安装相应的库。

    如果您需要进一步的帮助,请提供更多信息,我将尽力协助您解决问题。

    评论

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 9月25日
  • 创建了问题 9月24日

悬赏问题

  • ¥15 MYSQL 订单的商品明细重复计算问题
  • ¥15 微信实时共享位置修改
  • ¥100 TG的session协议号转成直登号号后客户端登录几分钟后自动退出设备
  • ¥30 共模反馈回路的小信号增益
  • ¥15 arduino ssd1306函数与tone函数放歌代码不兼容问题
  • ¥70 0.96版本hbase的row_key里含有双引号,无法deleteall
  • ¥40 Ida Pro增加插件出现问题
  • ¥15 诊断性META分析合并效能的检验
  • ¥15 请问abb根据色块判断奇偶数并根据批次号放入仓储
  • ¥66 开发PC客户端一定也要开发上位机吗?