Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BREAKGING CHANGE: v2 UI #19

Merged
merged 1 commit into from
Jun 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 18 additions & 2 deletions browser.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,31 +3,47 @@
from playwright.sync_api import Playwright, sync_playwright, expect


def run(playwright: Playwright) -> None:
def run(playwright: Playwright, progress_bar: str=None) -> None:
def set_progress(progress):
if progress_bar is not None:
progress_bar.set(progress)

browser = playwright.chromium.launch(headless=True)
context = browser.new_context()
page = context.new_page()
page.goto(config.RENDERING_URL)

time.sleep(10)
set_progress(40)

for i in range(10):
time.sleep(1)
set_progress(40 + i)

page.get_by_text("File").click()
set_progress(55)

with page.expect_file_chooser() as fc_info:
page.locator("[id=\"\\31 2\"]").click()
file_chooser = fc_info.value
file_chooser.set_files("temp/waiting_for_upload.schem")
page.get_by_text("File", exact=True).click()
set_progress(60)

page.locator("[id=\"\\32 3\"] > div:nth-child(3)").click()
with page.expect_download() as download_info:
page.locator("[id=\"\\31 8\"]").click()

set_progress(70)

download = download_info.value
download.save_as("temp/screenshot.png")
page.close()

context.close()
browser.close()

set_progress(90)

if __name__ == "__main__":
with sync_playwright() as playwright:
run(playwright)
10 changes: 5 additions & 5 deletions config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,22 @@
# GPT SETTINGS #
# Get your api key from openai. Remember google/bing is always your best friend.
# Model names: gpt-4-turbo-preview, gpt-3.5-turbo, etc.
# Recommend -> gpt-4-turbo-preview, which codes more accurately and is less likely to write bugs, but is more expensive.
# Recommend -> gpt-4-turbo (Better performance, more expensive), gpt-4-o (Good performance, cheaper)

API_KEY: "" # Free API Key with GPT-4 access: https://github.com/CubeGPT/.github/discussions/1
BASE_URL: "https://api.openai.com/v1/chat/completions"

GENERATE_MODEL: "gpt-4-turbo-preview" # Don't use gpt-4, because this model is longer supports json modes.
GENERATE_MODEL: "gpt-4-turbo" # Don't use gpt-4, because this model is longer supports json modes.


# ADVANCED MODE #
# This mode is experimental. But we highly recommend you to enable this mode for better performance.
ADVANCED_MODE: True
# This mode is experimental. This will enrich the aesthetics of the generated structure, but may affect the quality of the output to some extent. It also consumes more tokens when this mode is turned on, but we still recommend turning it on.
ADVANCED_MODE: False
IMAGE_GENERATION_MODEL: "dall-e-3"
IMAGE_SIZE: "1024x1024"
VISION_MODEL: "gpt-4-vision-preview"

# Note: If you are using the free API key above, you can't use the advanced mode since it doesn't support dall-e-3 and gpt-4-vision-preview models.
# Note: If you are using the free API key we provided, you can't use the advanced mode since it doesn't support dall-e-3 and gpt-4-vision-preview models.
USE_DIFFERENT_APIKEY_FOR_DALLE_MODEL: False
DALLE_API_KEY: ""
DALLE_BASE_URL: "https://api.openai.com/v1/chat/completions"
Expand Down
18 changes: 18 additions & 0 deletions cube_qgui/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Author: Acer Zhang
# Edit: CubeGPT Team
# Original Version Datetime: 2021/9/16
# Edited Version Datetime: 2024/5/31
# Copyright belongs to the author.
# Please indicate the source for reprinting.

import cube_qgui.base_tools
import cube_qgui.factory
# import qgui.notebook_tools
# import qgui.banner_tools


from cube_qgui.factory import CreateQGUI

from cube_qgui.manager import *

from cube_qgui.base_tools import ArgInfo
122 changes: 122 additions & 0 deletions cube_qgui/__main__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
import time

# 导入CreateQGUI模块
from qgui import CreateQGUI, MessageBox
# 【可选】导入自定义导航栏按钮模块、GitHub导航栏模块
from qgui.banner_tools import BaseBarTool, GitHub, AIStudio
# 【可选】一次性导入所有的主界面工具模块
from qgui.notebook_tools import *
# 【可选】导入占位符
from qgui.manager import QStyle, HORIZONTAL


def click(args: dict):
MessageBox.info("要开始啦~")
# 证明一下自己被点到了
print("你点到我啦~")
# 通过ChooseFileTextButton(name="文件选择")中预先设置的name参数,使用get方法即可获取对应的输入框信息
print("你选择的文件是:", args["文件选择"].get())
# 当然也可以通过name参数来设置对应的内容,使用set方法即可完成设置
print("保存位置修改为“快看,我被修改啦”", args["保存位置"].set("快看,我被修改啦"))
# 即使没有指定name,我们照样可以拿到所有的小工具情况
for arg, v_fun in args.items():
print("自定义组件Name:", arg, "状态:", v_fun.get())

# 若我们绑定了进度条,那么每当需要设置进度的时候,通过args["进度条"].set(当前进度)来进行设置吧,倒吸进度条也是可以哒
for i in range(1, 101):
time.sleep(0.01)
args["进度条"].set(i)
# 增加打印间隔
if i % 20 == 0:
print("当前进度", i)
MessageBox.warning(text="给个评价吧亲~")
# 也可以在终端中打印组件,顺便绑定用户调研函数
q_gui.print_tool(RadioButton(["满意", "一般", "你好垃圾啊"], title="体验如何?", name="feedback", bind_func=feedback))
# 甚至打印图片
from qgui import RESOURCES_PATH
q_gui.print_image(os.path.join(RESOURCES_PATH, "demo/panda.jpg"))


def feedback(args: dict):
# 用户调研Callback
info = args["feedback"].get()
if info == "满意":
print("么么哒")
elif info == "一般":
print("啊啊啊,告诉GT哪里没做好吧")
else:
print("以后漂流瓶见吧,拜拜!")


def bind_dir(args: dict):
# 获取所选择文件所在的文件夹路径
path = os.path.dirname(args["文件选择"].get())
# 可以通过name参数来设置对应的内容,使用set方法即可完成设置
args["保存位置"].set(path)
print("保存位置已自动修改为:", path)


def go_to_first_page(args: dict):
args["QGUI-BaseNoteBook"].set(0)


# 创建主界面
q_gui = CreateQGUI(title="一个新应用", # 界面标题
tab_names=["主控制台", "选择按钮", "其他小工具"], # 界面中心部分的分页标题 - 可不填
style=QStyle.default) # 皮肤

# 在界面最上方添加一个按钮,链接到GitHub主页
q_gui.add_banner_tool(GitHub(url="https://github.com/QPT-Family/QGUI"))
# 也可以是AI Studio
q_gui.add_banner_tool(AIStudio(url="https://aistudio.baidu.com/aistudio/personalcenter/thirdview/29724"))
# 要不试试自定义Banner按钮,在大家点击它时触发刚刚定义的click函数,并向它传递其他组件的情况
q_gui.add_banner_tool(BaseBarTool(bind_func=click, name="一个新组件"))

# 在主界面部分添加一个文件选择工具吧,并在选择文件后自动变为文件所在的路径
q_gui.add_notebook_tool(ChooseFileTextButton(name="文件选择", bind_func=bind_dir))
# 再加个文件夹选择工具
q_gui.add_notebook_tool(ChooseDirTextButton(name="保存位置"))
# 当然也可以来个输入框
q_gui.add_notebook_tool(InputBox(name="我是个木有感情的输入框"))
# 想要加一个 进度条 和 运行按钮 而且俩要水平方向排列该如何做?
# 试试HorizontalToolsCombine,它可以接受一组工具并将其进行水平排列
# 这里我们也为RunButton绑定click函数
run_menu = HorizontalToolsCombine([Progressbar(name="进度条"),
RunButton(bind_func=click)],
text="试试HorizontalToolsCombine,它可以接受一组工具并将其进行水平排列")
q_gui.add_notebook_tool(run_menu)

# 第二页 - 复选框和单选框
# 使用VerticalFrameCombine可以将他们在垂直方向快速组合,它们会从左到右按顺序排列
combine_left = VerticalFrameCombine([CheckButton(options=[("选择1", 0), ("选择2", 1), ("选择3", 0)]),
CheckToolButton(options=[("选择1", 0), ("选择2", 1), ("选择3", 0)]),
CheckObviousToolButton(options=[("选择1", 0), ("选择2", 1), ("选择3", 0)]),
ToggleButton(options=("开", 1))],
tab_index=1,
text="使用VerticalFrameCombine可以将他们在垂直方向快速组合,它们会从左到右按顺序排列")
q_gui.add_notebook_tool(combine_left)
# 设置title参数后会为其增加标题
combine_right = VerticalFrameCombine([RadioButton(["选择1", "选择2", "选择3"], tab_index=1),
RadioToolButton(["选择1", "选择2", "选择3"], tab_index=1),
RadioObviousToolButton(["选择1", "选择2", "选择3"], tab_index=1)],
title="右侧的复选框")
q_gui.add_notebook_tool(combine_right)

# 第三页
q_gui.add_notebook_tool(Label(text="这只是个简单的Label组件", alignment=RIGHT + TOP, tab_index=2))
q_gui.add_notebook_tool(Slider(default=4, tab_index=2))
q_gui.add_notebook_tool(Combobox(options=["选择1", "选择2", "选择3"], tab_index=2))
q_gui.add_notebook_tool(BaseButton(bind_func=go_to_first_page, text="回到首页", tab_index=2))

# 左侧信息栏
# 简单加个简介
q_gui.set_navigation_about(author="GT",
version="0.0.1",
github_url="https://github.com/QPT-Family/QGUI",
other_info=["欢迎加入QPT!"])
# 也可以加一下其他信息
q_gui.set_navigation_info(title="随便写段话", info="除了QGUI,你还可以试试例如AgentQGUI这样同样简单的GUI框架")
print("小Tips:占位符可以被Print,不信你看HORIZONTAL的描述被打印了出来->", HORIZONTAL)

# 跑起来~切记!一定要放在程序末尾
q_gui.run()
106 changes: 106 additions & 0 deletions cube_qgui/banner_tools.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
# Author: Acer Zhang
# Datetime: 2021/9/16
# Copyright belongs to the author.
# Please indicate the source for reprinting.
import os
import webbrowser

import tkinter
from tkinter import ttk
from cube_qgui.manager import ICON_PATH, ConcurrencyModeFlag
from cube_qgui.base_tools import ArgInfo, BaseTool

RUN_ICON = os.path.join(ICON_PATH, "play_w.png")
GITHUB_ICON = os.path.join(ICON_PATH, "github.png")
AI_STUDIO_ICON = os.path.join(ICON_PATH, "up_cloud.png")


class BaseBarTool(BaseTool):
"""
基础Banner工具集
需注意的是,如需增加异步等操作,请为函数添加_callback
"""

def __init__(self,
bind_func,
name="Unnamed Tool",
icon=None,
style=None,
async_run: bool = True,
concurrency_mode=ConcurrencyModeFlag.SAFE_CONCURRENCY_MODE_FLAG):
super().__init__(bind_func=bind_func,
name=name,
style=style,
async_run=async_run,
concurrency_mode=concurrency_mode)

if icon and not os.path.exists(icon):
raise f"Please check if {os.path.abspath(icon)} exists."
if not icon:
icon = RUN_ICON
self.icon = icon

def build(self, *args, **kwargs):
super().build(*args, **kwargs)
self.img = tkinter.PhotoImage(file=self.icon)

btn = ttk.Button(self.master,
text=self.name,
image=self.img,
compound="left",
command=self._callback(self.bind_func) if self.async_run else self.bind_func,
style=self.style + "TButton")

btn.pack(side="left", ipadx=5, ipady=5, padx=0, pady=1)


class RunTool(BaseBarTool):
def __init__(self,
bind_func,
name="Start Processing",
icon=None,
style="success",
async_run: bool = True,
concurrency_mode=ConcurrencyModeFlag.SAFE_CONCURRENCY_MODE_FLAG):
if not icon:
icon = RUN_ICON
super(RunTool, self).__init__(bind_func,
name=name,
icon=icon,
style=style,
async_run=async_run,
concurrency_mode=concurrency_mode)


class GitHub(BaseBarTool):
def __init__(self,
url,
name="View on GitHub",
style="primary"):
icon = GITHUB_ICON
bind_func = self.github_callback
super().__init__(bind_func,
name=name,
icon=icon,
style=style)
self.github_url = url

def github_callback(self, args):
webbrowser.open_new(self.github_url)


class AIStudio(BaseBarTool):
def __init__(self,
url,
name="Use on AI Studio",
style="primary"):
icon = AI_STUDIO_ICON
bind_func = self.ai_studio_callback
super().__init__(bind_func,
name=name,
icon=icon,
style=style)
self.ai_studio_url = url

def ai_studio_callback(self, args):
webbrowser.open_new(self.ai_studio_url)
Loading
Loading