如何捕捉 Qwidget 焦点丢失 (PyQt5)。
失去焦点时必须关闭应用程序。
biomotor's questions
tksvg 库是否能够直接从代码而不是从文件中读取 svg?如果是这样,怎么做?
在 PyQt5 中找到了一个示例,在 tksvg 或 tkinter 中是否有类似的东西?
def iconFromBase64(base_64):
pixmap = QtGui.QPixmap()
pixmap.loadFromData(QtCore.QByteArray.fromBase64(base_64), "SVG")
icon = QtGui.QIcon(pixmap)
return icon
...
self.svg_str = """
<svg width="210pt" height="210pt" viewBox="0 0 210 210">....</svg>
"""
svg_base64_str = b64encode(self.svg_str.encode('utf-8'))
self.icon = iconFromBase64(svg_base64_str)
self.pb.setIcon(self.icon)
...
我正在写一个应用程序:
if __name__ == "__main__":
root = Tk()
root.configure()
root.mainloop()
一切似乎都很美好,Tk 窗口启动。但是,如果我在 PyScripter 中使用“调试崩溃”功能,则会收到错误消息:
Traceback (most recent call last):
File "C:\Users\User\Desktop\Python File.py", line 9, in <module>
root.mainloop()
File "C:\ProgramData\ASCON\KOMPAS-3D\19\Python 3\App\lib\tkinter\__init__.py", line 1429, in mainloop
self.tk.mainloop(n)
KeyboardInterrupt
是否有可能以某种方式从 PyScripter 停止程序而不会出现此错误?
(我正在编写一个没有通常框架的程序,因此我无法从窗口完成它......)
我想使用 winreg 访问注册表。
来自互联网的例子:
Winreg(winreg.HKEY_CURRENT_USER, r"SOFTWARE\\RegTest\\test1")
我想使用这样的东西:
def addreg(r'HKEY_CURRENT_USER\\SOFTWARE\\RegTest\\test1')
问题 1:如何从字符串中去除 HKEY_CURRENT_USER?
问题2: python函数中是否有将字符串'HKEY_CURRENT_USER'转换为winreg.HKEY_CURRENT_USER引用的函数?
(我不想为每个注册表项写 if ... Winreg(winreg...) 5 次)
任务:我想通过 call() 更改窗口框架 tk.Tk() highlightbackground 和 highlightcolor 的颜色。
原来:通过tcl改,但是不知道怎么用call……有什么指令吗?
发现如何使用:
#root.overrideredirect(1)
#root.after_idle(root.attributes, '-topmost', True)
root.call('wm', 'overrideredirect', '.', 1)
root.call('wm', 'attributes', '.', '-topmost', True)
简单的例子:
import tkinter as tk
import tksvg
window = tk.Tk()
svg_image = tksvg.SvgImage(master=window, file="128.svg", scale=1)
label = tk.Label(bg='#CCCCCC', image=svg_image, borderwidth=0, relief="solid")
print(label.winfo_reqwidth(), label.winfo_reqheight())
label.pack()
window.mainloop()
128.svg - 128x128 像素。
问题:如何将 tksvg 图像的尺寸设置为 pix?
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from PyQt5.QtWidgets import *
from PyQt5.QtGui import QKeySequence, QPalette, QColor
from PyQt5.QtCore import Qt
app = QApplication([])
palette = QPalette()
palette.setColor(QPalette.Window, QColor(53, 53, 53))
如何读取当前设置的 Window 的颜色值?
你能告诉我如何在 PyScripter 中设置类似于 PyCharm 中的 Darcula 的主题和方案吗?
我有一个程序代码,它在树视图中显示来自 xml 文件的数据。
from tkinter import *
from tkinter.ttk import Treeview
import xml.etree.ElementTree as ET
class App:
def __init__(self, root):
try:
with open('FileInfo.xml') as f:
read_data = f.read()
ansi = read_data.encode('ansi')
rootNode = ET.fromstring(ansi)
self.tree = Treeview(root)
self.tree.pack(expand=True, fill='both')
self.tree.heading('#0', text=rootNode.get('displayName'), anchor='w')
self.walk_dict(rootNode)
except Exception as e:
print(e)
def walk_dict(self, d, depth=0, parent=""):
for child in d:
if(child.tag == 'folder'):
item = self.tree.insert(parent, 'end', None, text=child.get('displayName'))
elif(child.tag == 'element'):
item = self.tree.insert(parent, 'end', None, text=child.get('file'))
if child.__len__() > 0:
self.walk_dict(child, depth + 1, parent=item)
root = Tk()
root.geometry("500x600")
App(root)
root.mainloop()
包含内容的 XML 文件:
<?xml version="1.0"?>
<library displayName="MyLibrary">
<description />
<folder displayName="9_">
<folder displayName="9_">
<element displayName="9_" file="9_.kdw" />
<description>Description.</description>
<element displayName="1_" file="1_.kdw" />
<element displayName="я_" file="я_.kdw" />
<element displayName="а_" file="а_.kdw" />
<element displayName="z_" file="z_.kdw" />
<element displayName="a_" file="a_.kdw" />
</folder>
<folder displayName="1_">
<element displayName="9_" file="9_.kdw" />
</folder>
<folder displayName="я_">
<element displayName="9_" file="9_.kdw" />
</folder>
<folder displayName="а_">
<element displayName="9_" file="9_.kdw" />
</folder>
<folder displayName="z_">
<element displayName="9_" file="9_.kdw" />
</folder>
<folder displayName="a_">
<element displayName="9_" file="9_" />
</folder>
</folder>
<folder displayName="1_">
<element displayName="9_" file="9_.kdw" />
</folder>
<folder displayName="я_">
<element displayName="9_" file="9_.kdw" />
</folder>
<folder displayName="а_">
<element displayName="9_" file="9_" />
</folder>
<folder displayName="z_">
<element displayName="9_" file="9_.kdw" />
</folder>
<folder displayName="a_">
<element displayName="9_" file="9_.kdw" />
</folder>
<element displayName="9_" file="9_.kdw" />
<element displayName="1_" file="1_.kdw" />
<element displayName="я_" file="я_.kdw" />
<element displayName="а_" file="а_.kdw" />
<element displayName="z_" file="z_.kdw" />
<element displayName="a_" file="a_.kdw" />
</library>
有必要对所有目录和文件进行排序。1-999...,az,a-z。
显然排序应该在这里的某个地方......
ansi = read_data.encode('ansi')
....
rootNode = ET.fromstring(ansi)
这是我目前得到的:
需要将字典和变量写入settings.ini文件,(**如果文件不存在,则创建)
字典准备:
dict1 = [
{'object': 'label', 'icon': 'icon', 'icon_hover': 'icon_hover', 'command': 'command'},
{'object': 'button', 'icon': 'icon', 'icon_hover': 'icon_hover', 'command': 'command'},
{'object': 'color', 'icon': 'icon', 'icon_hover': 'icon_hover', 'command': 'command'},
{'object': 'line', 'icon': 'icon', 'icon_hover': 'icon_hover', 'command': 'command'},
{'object': 'unknown', 'icon': 'icon', 'icon_hover': 'icon_hover', 'command': 'command'},
]
变量:
theme = light
icon_size = 32
indent = 36
问题:
最方便的方法是什么?配置解析器、yaml 还是 json?(重要的是该文件被称为“settings.ini”)
目前我只能设置1-9个输入文件进行处理,
伪代码:
@echo off
@color 0f
attrib -r "%~1"
.....
attrib -r "%~9"
pause
你需要得到超过这个值(% ~ 10+),最好通过循环简化它,告诉我如何实现它?
告诉我,为什么再次调用 ConfigParser 会丢失注释?
(第一次打开时,添加了注释,然后从代码中删除,再次打开时,它们消失了,如何使它们不消失?)
解析器主要代码:
from configparser import ConfigParser
class MyCfg(ConfigParser):
def __init__(self, file: str='cfg.ini'):
self.file = file
self.optionxform = str
return super(MyCfg, self).__init__(allow_no_value=True)
def __getitem__(self, item):
try:
return super(MyCfg, self).__getitem__(item)
except KeyError:
self.add_section(item)
return super(MyCfg, self).__getitem__(item)
def __setitem__(self, item, val):
if val[0] == '#' or val[0] == ';':
self.__getitem__(item)
return super(MyCfg, self).set(item, val)
def read(self):
return super(MyCfg, self).read(self.file)
def write(self):
with open(self.file, 'w') as fp:
return super(MyCfg, self).write(fp)
if __name__ == '__main__':
cfg = MyCfg('settings.ini')
cfg.read()
cfg['section'] = '# Комментарий 1'
cfg['section']['option'] = 'option_value2'
cfg['section'] = '# Комментарий 2'
cfg['section']['tag'] = 'tag_value'
cfg['section'] = '# Комментарий 3'
cfg['another_section']['test'] = 'test_value'
cfg.write()
我有一个例子:
self.m = Menu(self.c, tearoff=0)
self.m["bg"] = 'white'
self.m["activebackground"] = 'gray'
如何为函数设置参数,以便我可以通过调用读取def myname():
并通过调用更改self.myname["bg"]
self.myname["bg"] = 'white'
伪代码:
myname = self.myname()
myname['bg'] = 'gray'
def myname(self, bg):
self.bg = bg
print(self.bg)
__init__.py
在tkinter 文件中找到有关 Menu 的信息:
class Menu(Widget):
def __init__(self, master=None, cnf={}, **kw):
Widget.__init__(self, master, 'menu', cnf, kw)
...
def add(self, itemType, cnf={}, **kw):
"""Internal function."""
self.tk.call((self._w, 'add', itemType) +
self._options(cnf, kw))
告诉我字典是如何工作的cnf={}
???
发现了别的东西:
class BaseWidget(Misc):
...
def __init__(self, master, widgetName, cnf={}, kw={}, extra=()):
"""Construct a widget with the parent widget MASTER, a name WIDGETNAME
and appropriate options."""
if kw:
cnf = _cnfmerge((cnf, kw))
self.widgetName = widgetName
BaseWidget._setup(self, master, cnf)
if self._tclCommands is None:
self._tclCommands = []
classes = [(k, v) for k, v in cnf.items() if isinstance(k, type)]
for k, v in classes:
del cnf[k]
self.tk.call(
(widgetName, self._w) + extra + self._options(cnf))
for k, v in classes:
k.configure(self, v)
如何正确地将 place、pack 和 grid 方法重新分配为类的一部分?
您需要确保未设置的参数被那些在原始位置、包装和网格方法中默认设置的参数使用。
我的例子(但我不确定它是否正确):
def place(self, x=None, y=None):
self.canvas.place(x=x, y=y)
def pack(self, fill=None, expand=None, side=None, anchor=None, padx=None, pady=None):
self.canvas.pack(fill=fill, expand=expand, side=side, anchor=anchor, padx=padx, pady=pady)
def grid(self, row=None, column=None, columnspan=None, sticky=None, rowspan=None, padx=None, pady=None):
self.canvas.grid(row=row, column=column, columnspan=columnspan, sticky=sticky, rowspan=rowspan, padx=padx, pady=pady)
也许这更好?:
def place(self, *args):
self.canvas.place(*args)
def pack(self, *args):
self.canvas.pack(*args)
def grid(self, *args):
self.canvas.grid(*args)
不能在类的开头检查变量的存在,告诉我如何实现它?
类代码开始:
class MButton():
def __init__(self, *arg):
self.parent = arg[0]
self.limage = arg[1]
self.lcommand = arg[2]
self.rcommand = arg[3]
尝试过这样的事情:,
(还有更多选择......)
try:
arg[4]
except IndexError:
arg[4] = None
问题2:
如果这些选项怎么办?允许吗?什么更好?
选项1:
Вызов:
self.test = MTest(width=10, height=10, **{'bdsize':1, 'bgcolor':2, 'parent':3})
class MTest():
def __init__(self, width, height, **args):
self.width=width
self.height=height
self.bdsize=args['bdsize']
self.bgcolor=args['bgcolor']
self.bdcolor=args['bdcolor']
self.parent=args['parent']
选项 2:
Вызов:
self.test = MTest(**{'width':10, 'height':10, 'bdsize':1, 'bgcolor':2, 'parent':3})
class MTest():
def __init__(self, **args):
self.width=args['width']
self.height=args['height']
self.bdsize=args.get('bdcolor')
self.bgcolor=args.get('bdcolor')
self.bdcolor=args.get('bdcolor')
self.parent=args.get('bdcolor')
选项 3:
Вызов:
self.test = MTest(**{'width':10, 'height':10, 'bdsize':1, 'bgcolor':2, 'parent':3})
class MTest():
def __init__(self, **args):
self.width=args.get('width')
self.height=args.get('height')
self.bdsize=args.get('bdcolor')
self.bgcolor=args.get('bdcolor')
self.bdcolor=args.get('bdcolor')
self.parent=args.get('bdcolor')
if not self.width == None or self.height == None:
raise Exception('ERROR: Проверьте правильность введенных данных обязательных параметров width и height !')
选项 4:
Вызов:
self.test = MTest(width=10, height=10, bdsize=1, parent=3)
class MTest():
def __init__(self, **args):
self.width=args['width']
self.height=args['height']
self.bdsize=args.get('bdsize')
self.parent=args.get('parent')
self.bgcolor=args.get('bgcolor')
self.bdcolor=args.get('bdcolor')
选项 5:
Вызов:
self.test = MTest(width=10, height=10, bdsize=1, parent=3)
class MTest():
def __init__(self, width, height, bdsize=None, bgcolor=None, bdcolor=None, parent=None):
self.width=width
self.height=height
self.bdsize=bdsize
self.bgcolor=bgcolor
self.bdcolor=bdcolor
self.parent=parent
告诉我如何正确组织从 tkinter.Button 继承的按钮(添加图标(通过添加属性改进标准 tkinter.Button))
到目前为止,我已经停在那里了。我的错误是什么?如何正确组织pack()的工作?
from tkinter import *
root = Tk()
class myButton(Button):
def __init__(self, text, width, height):
self._text = text
self._width = width
self._height = height
def text(self, _text):
text = _text
def width(self, _width):
width = _width
def height(self, _height):
height = _height
b2 = myButton(text="Изменить", width=15, height=3)
b2.pack()
root.mainloop()
打印属性
我想在打印示例中添加更多属性,但是没有用,为什么?
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from tkinter import *
root = Tk()
class myButton(Button):
def __init__(self, text, width, height, print): #Испр.
super().__init__(text=text, width=width, height=height)
self._text = text
self._width = width
self._height = height
self._print = print #Испр.
def text(self, _text):
text = _text
def width(self, _width):
width = _width
def height(self, _height):
height = _height
def print(self, _print): #Испр.
print(_print) #Испр.
b2 = myButton(text="123", width=15, height=3, print = "111") #Испр.
b2.pack()
root.mainloop()
告诉我在哪里可以下载源代码QToolBar.py
和QPushButton.py
?
我想弄清楚它是如何工作的……我找到了https://antonz.ru/python-sources/但我没有看到开发人员 github 本身的链接。
附加问题1:
例子:
self.TOOLBAR = QtWidgets.QToolBar(MainWindow)
self.TOOLBAR.setEnabled(False)
self.TOOLBAR.setStyleSheet("SETSTYLESHEET")
self.TOOLBAR.setMovable(False)
self.TOOLBAR.setAllowedAreas(QtCore.Qt.NoToolBarArea)
self.TOOLBAR.setOrientation(QtCore.Qt.Horizontal)
self.TOOLBAR.setToolButtonStyle(QtCore.Qt.ToolButtonIconOnly)
self.TOOLBAR.setFloatable(False)
self.TOOLBAR.setObjectName("TOOLBAR")
我希望它是这样的:
self.TOOLBAR = KWidgets.KToolBar(MainWindow)
self.TOOLBAR.setEnabled(False)
self.TOOLBAR.setStyleSheet("SETSTYLESHEET")
self.TOOLBAR.setMovable(False)
self.TOOLBAR.setAllowedAreas(QtCore.Qt.NoToolBarArea)
self.TOOLBAR.setOrientation(QtCore.Qt.Horizontal)
self.TOOLBAR.setToolButtonStyle(QtCore.Qt.ToolButtonIconOnly)
self.TOOLBAR.setFloatable(False)
self.TOOLBAR.setObjectName("TOOLBAR")
(因此,应该有从 QToolBar 继承 KToolBar 并分配某些参数)
附加问题2:
在主要(调用)中:
self.toolbar = KWidgets.KToolBar(self.mwidget)
# тут нужно вызвать setIconSize
在 KWidgets.py 文件中:
from PyQt5.QtWidgets import QToolBar
class KToolBar(QToolBar):
pass
# тут нужно вызвать setStyleSheet
我正在尝试制作一个设置文件(colors.py) 最重要的是,当更改“THEME =”的值时,变量被分配了一个特定的值。在这种情况下,一切都很美好,但它说变量不是全局的,每次都引用这个函数不是一个选项。通过全局声明每个变量是另一项任务......告诉我如何正确和简单地注册所有变量?
THEME = "Light" # Light, Dark, WLight, WDark
ICONS = "Colors" # Colors, Monochrome
def Light():
# главные цвета программы
color_background = "#F2F2F2"
color_background_hover = "#E5E5E5"
color_border = "#666666"
# цвета иконки перемещения
color_label = "#333333"
color_label_hover = "#666666"
# цвета иконок главного меню
if ICONS == "Colors": color_icon = "#3497D8"; color_icon_select = "#ff6a00";
elif ICONS == "Monochrome": color_icon = "#333333"; color_icon_select = "#00000000";
# цвета подгрупп
color_group_background = "#F2F2F2"
color_group_border = "#D3D3D3"
color_group_border_hover = "#B6B6B6"
# цвета контекстного меню
color_context_background = "#FFFFFF"
color_context_background_hover = "#333333"
color_context_border = "#333333"
def Dark():
...
def WLight():
...
def WDark():
...
if THEME == "Light": Light()
elif THEME == "Dark": Dark()
elif THEME == "WLight": WLight()
elif THEME == "WDark": WDark()
这个问题被另一个人解决了,如果:
# Настройки цветов
THEME = "Light" # Light, Dark, WLight, WDark
ICONS = "Colors" # Colors, Monochrome
if THEME == "Light":
# главные цвета программы
color_background = "#F2F2F2"
color_background_hover = "#E5E5E5"
color_border = "#666666"
# цвета иконки перемещения
color_label = "#333333"
color_label_hover = "#666666"
# цвета иконок главного меню
if ICONS == "Colors": color_icon = "#3497D8"; color_icon_select = "#ff6a00";
elif ICONS == "Monochrome": color_icon = "#333333"; color_icon_select = "#00000000";
# цвета подгрупп
color_group_background = "#F2F2F2"
color_group_border = "#D3D3D3"
color_group_border_hover = "#B6B6B6"
# цвета контекстного меню
color_context_background = "#FFFFFF"
color_context_background_hover = "#333333"
color_context_border = "#333333"
print ("Light")
elif THEME == "Dark":
...
elif THEME == "WLight":
...
elif THEME == "WDark":
...
附加问题2:
单击按钮时无法嵌入动态主题更改,以及如何将其正确导入 icon.py?
main.py 文件
from PyQt5.QtWidgets import QApplication, QPushButton, QMainWindow, QFrame, QLabel, QMenu
from PyQt5 import QtCore, QtWidgets, QtGui
from PyQt5.QtCore import QPoint
from PyQt5 import QtWidgets as qtw
from PyQt5.QtGui import QPixmap
from PyQt5.QtSvg import QSvgWidget, QSvgRenderer
class Ui_MainWindow(QMainWindow):
# --- Основное Окно Программы ---
def __init__(self):
super().__init__()
self.mwidget = QMainWindow(self)
self.setWindowFlags(QtCore.Qt.Tool | QtCore.Qt.FramelessWindowHint | QtCore.Qt.WindowStaysOnTopHint)
self.setGeometry(QtCore.QRect(100, 100, 200, 200))
self.pbx1 = QPushButton(self)
self.pbx1.setObjectName("pbx1")
self.pbx1.setGeometry(QtCore.QRect(1, 15, 45, 45))
icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap("G4.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.pbx1.setIcon(icon)
self.pbx1.setIconSize(QtCore.QSize(30, 30))
self.pbx1.clicked.connect(lambda: self.setTheme(themes.ThemeDark))
# --- Показать Окно ---
self.show()
def setTheme(Theme):
theme=Theme
# --- Запуск Окна Программы ---
if __name__ == "__main__":
import themes
theme=themes.ThemeLight
button=themes.ButtonColors
import sys
app = QApplication(sys.argv)
ex = Ui_MainWindow()
sys.exit(app.exec_())
主题.py 文件
class ThemeLight:
# главные цвета программы
color_background = "#F2F2F2"
color_background_hover = "#E5E5E5"
color_border = "#666666"
# цвета иконки перемещения
color_label = "#333333"
color_label_hover = "#666666"
# цвета подгрупп
color_group_background = "#F2F2F2"
color_group_border = "#D3D3D3"
color_group_border_hover = "#B6B6B6"
# цвета контекстного меню
color_context_background = "#FFFFFF"
color_context_background_hover = "#333333"
color_context_border = "#333333"
class ThemeDark:
color_background = "#000000"
# ...
class ThemeWLight:
color_background = ""
# ...
class ThemeWDark:
color_background = ""
# ...
class ButtonColors:
color_icon = "#3497D8"
color_icon_select = "#ff6a00"
class ButtonMonochrome:
color_icon = "#333333"
color_icon_select = "#00000000"
图标.py 文件
import themes
theme=themes.ThemeLight
CL = theme.color_label
# Иконка Label вертикальная
icon_label_vertical = """
<svg>
<path fill="%s" opacity="1.00" d=" M 154.00 14.00 C 158.66 14.00 163.33 14.00 168.00 14.00 C 167.99 18.67 168.00 23.33 168.00 28.00 C 163.33 28.00 158.67 28.00 154.00 28.00 C 153.99 23.33 154.00 18.67 154.00 14.00 Z" />
</svg>""" % CL
点击按钮:
Process finished with exit code -1073740791 (0xC0000409)
附加问题3:
为什么 setStyleSheet 不改变颜色?
主题.py:
class ThemeLight:
test = "#FF0000"
class ThemeDark:
test = "#00FF00"
主要.py:
from PyQt5.QtWidgets import QApplication, QPushButton, QMainWindow, QFrame, QLabel, QMenu
from PyQt5 import QtCore, QtWidgets, QtGui
from PyQt5.QtCore import QPoint
from PyQt5 import QtWidgets as qtw
from PyQt5.QtGui import QPixmap
from PyQt5.QtSvg import QSvgWidget, QSvgRenderer
import icons, themes
class Ui_MainWindow(QMainWindow):
# --- Основное Окно Программы ---
def __init__(self):
super().__init__()
self.mwidget = QMainWindow(self)
self.setWindowFlags(QtCore.Qt.Tool | QtCore.Qt.FramelessWindowHint | QtCore.Qt.WindowStaysOnTopHint)
self.setGeometry(QtCore.QRect(100, 100, 200, 200))
self.setStyleSheet("""
QFrame#frame {
background-color: %s;
}
""" % theme.test)
self.frame = QFrame(self)
self.frame.setObjectName("frame")
self.frame.setGeometry(QtCore.QRect(0, 0, 200, 200))
print (theme.test)
self.pbx1 = QPushButton(self)
self.pbx1.setObjectName("pbx1")
self.pbx1.setGeometry(QtCore.QRect(1, 15, 45, 45))
self.pbx1.clicked.connect(lambda: setTheme(themes.ThemeDark))
# --- Показать Окно ---
self.show()
def setTheme(Theme):
theme=Theme
print (theme.test)
# --- Запуск Окна Программы ---
if __name__ == "__main__":
theme=themes.ThemeLight
import sys
app = QApplication(sys.argv)
ex = Ui_MainWindow()
sys.exit(app.exec_())
我在主窗口中尝试这样:
def __init__(self):
...
self.setStyleSheet("Light.css")
在 Light.css 文件中:
QFrame#frame {
border: 1px solid #666666;
}
QPushButton {
background-color: #E5E5E5;
border: 1px solid #666666;
}
QPushButton:hover {
background-color: #666666;
border: 1px solid #000000;
}