I have a kivy app, here's the code:
class ComicNotificatorApp(App):
def build(self):
Window.size = (300, 300)
self.title = 'Comics Notificator'
self.icon = 'assets/icon.png'
return Label(text=to_display)
and I'd like to change the taskbar icon of the app
and while I'm at it, how can I change the size of the window to automatically fit the size of the label, as opposed to setting it manually?
Thank you!
stackoverflow question <-- this link mention a similar question and I think this may help
kivy doc for your ref about kivy config object
and I only know how to change the window's icon but not the task bar one
...
class MyKivyApp(App):
def build(self):
self.title = 'window's title'
self.icon = <icon>: str <----
...
the taskbar one maybe you can change it when packaging
how can I change the size of the window to automatically fit the size of the label
maybe you can try to use the kivy.config.Config.set() , if I get it correctly , you want to set the size of the window == size of label ? if so then set the size of the label first, then use kivy.config.Config.set('graphics', 'width', <size>: str) kivy.config.Config.set('graphics', 'height', <size>: str)
# I assume you won't change the label size after starting the kivy screen 😅
import kivy
kivy.config.Config.set('graphics', 'width', <label_width>: str)
kivy.config.Config.set('graphics', 'width', <label_height>: str)
...
because the config have to set at the very beginning , before the kivy window is created
e.g.
import kivy
# set config here
# import another stuff
hope this help : )
A bit late but for your main question Is it possible to change a kivy app taskbar icon, no it isn't possible to change the taskbar icon if you are running the app as a script, not an executable of some kind. However, the taskbar icon will automatically sync with your window icon when run as an executable(by packaging your app using pyinstaller or py2exe, anything like that could work)
Related
Hey there i am new to kivy and am using Python 3.8.10 and Kivy version: 2.1.0
i am trying to get the window resize working and pulled this working example.
I am on ElementaryOS
When i run the following code and resize the window, it jumps around the screen towards the left bottom corner and is super jittery, when resizing to full screen the content is not staying center but moving to the left bottom corner...
# To change the kivy default settings
# we use this module config
from kivy.config import Config
# 0 being off 1 being on as in true / false
# you can use 0 or 1 && True or False
Config.set('graphics', 'resizable', True)
# import kivy module
import kivy
# this restrict the kivy version i.e
# below this kivy version you cannot use the app
kivy.require("1.9.1")
# base Class of your App inherits from the App class.
# app:always refers to the instance of your application
from kivy.app import App
# if you not import label and use it through error
from kivy.uix.label import Label
# defining the App class
class MyLabelApp(App):
def build(self):
# label display the text on screen
# markup text with different colour
l2 = Label(text ="[color = ff3333][b]Hello !!!!!!!!!!![/b] [color]\n [color = 3333ff]GFG !!:):):):)[/color]",
font_size ='20sp', markup = True)
return l2
# creating the object
label = MyLabelApp()
# run the window
label.run()
I'm playing around with a Kivy Scrollview, adding scrollbars, etc, and getting a strange crash. I don't specifically think it's a bug, it's probably some configuration element on Scrollviews that I'm missing, but who knows?
Given this code:
"""
Source: https://stackoverflow.com/questions/35626320/kivy-image-scrolling
"""
from kivy.app import App
from kivy.uix.image import Image
from kivy.uix.scrollview import ScrollView
from kivy.core.window import Window
class TutorialApp(App):
def build(self):
some_img = Image(source='/home/data/map/Map_07C.jpg', size_hint=(None, None),
keep_ratio=True, size=(Window.width * 2, Window.height * 2))
sv = ScrollView(size=Window.size, bar_width=50,
scroll_type=['bars', 'content'], effect_cls='ScrollEffect')
sv.add_widget(some_img)
return sv
if __name__ == "__main__":
TutorialApp().run()
if I click or touch the Scrollbars in any way, I get this error:
File "kivy_env/lib/python3.8/site-packages/kivy/uix/scrollview.py", line 908, in on_scroll_move
self.effect_x.update(touch.x)
File "kivy_env/lib/python3.8/site-packages/kivy/effects/scroll.py", line 116, in update
self.displacement += abs(val - self.history[-1][1])
IndexError: list index out of range
However - if I first click the bitmap being scrolled, I can use the scrollbars with no problem.
So what's up? Is there some Scrollview configuration I'm missing? (It took me a while to even find the scroll_type option to enable the bars, at first I could only mouse-drag the bitmap). Or is it a bug - given that it's referencing history[-1], maybe that doesn't exist yet?
Yep, it's a bug. Just searched the Kivy repo on Github, found:
Effects Scroll Exception
The link does have a "workaround" patch, that you can manually apply to the installed library. Just tested the patch, it fixes my problem. Basically puts a try/except/return block around the line with history[-1]
technically is a bug but we can note from the desktop and mobile apps that they use different scroll_type=['bars', 'content'] in the desktop app we use bars
and in the mobile app we use content so the bug only occurs when we use two types of scroll_type so we can say that the scrollview does not design to use two type of scroll_type in the same time
Another workaround is calling a function on_touch_down that checks the mouse's x-position and changes the scroll type to either only ['Bars'] or only ['Content'] accordingly. Note, I set mine to check Window.width - 12 as that is the width of scroll bar that I use. Default is 2.
# tutorial.kv
<SV>:
on_touch_down: self.check_pos()
bar_width: 12
# main.py
from kivy.uix.scrollview import ScrollView
class SV(ScrollView):
def check_pos(self):
if Window.mouse_pos[0] <= (Window.width - 12):
self.scroll_type = ['content']
else:
self.scroll_type = ['bars']
My os is windows10 Chinese version. for input Chinese charactor, I use an IME to select word, like this:
but on a Kivy application, the Textinput widget can not activate IME select panel. for example, when i run the login demo from Kivy:
from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput
class LoginScreen(GridLayout):
def __init__(self, **kwargs):
super(LoginScreen, self).__init__(**kwargs)
self.cols = 2
self.add_widget(Label(text='User Name'))
self.username = TextInput(multiline=False)
self.add_widget(self.username)
self.add_widget(Label(text='password'))
self.password = TextInput(password=True, multiline=False)
self.add_widget(self.password)
class MyApp(App):
def build(self):
return LoginScreen()
if __name__ == '__main__':
MyApp().run()
The app screen is:
No IME select panel popup. What i expect is:
I searched doc from Kivy homepage, all IME related pages are about mobile device, not windows.
Please help.
Finally, i change the source code of SDL2, and compile a new dll to fix it. sure it's not a good solution, but the only i've found.
download SDL2 source code here: libsdl.org
find a file named "SDL_windowskeyboard.c", open it, add a macro definition:
rebuild it, make sure choose the correct platform(win32 or x64), then copy generated dll to overwrite the original one. In my project, the sdl package is in venv envirement "venv\share\sdl2\bin"
I'm trying to create an application that contains a web browser within it, but when I add the web browser my menu bar visually disappears but functionally remains in place. The following are two images, one showing the "self.centralWidget(self.web_widget)" commented out, and the other allows that line to run. If you run the example code, you will also see that while visually the entire web page appears as if the menu bar wasn't present, you have to click slightly below each entry field and button in order to activate it, behaving as if the menu bar was in fact present.
Web Widget Commented Out
Web Widget Active
Example Code
import os
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtWebEngineWidgets import *
class WebPage(QWebEngineView):
def __init__(self, parent=None):
QWebEngineView.__init__(self)
self.current_url = ''
self.load(QUrl("https://facebook.com"))
self.loadFinished.connect(self._on_load_finished)
def _on_load_finished(self):
print("Url Loaded")
class MainWindow(QMainWindow):
def __init__(self, parent=None):
# Initialize the Main Window
super(MainWindow, self).__init__(parent)
self.create_menu()
self.add_web_widet()
self.show()
def create_menu(self):
''' Creates the Main Menu '''
self.main_menu = self.menuBar()
self.main_menu_actions = {}
self.file_menu = self.main_menu.addMenu("Example File Menu")
self.file_menu.addAction(QAction("Testing Testing", self))
def add_web_widet(self):
self.web_widget = WebPage(self)
self.setCentralWidget(self.web_widget)
if __name__ == "__main__":
app = QApplication(sys.argv)
main_window = MainWindow()
main_window.showMaximized()
sys.exit(app.exec_()) # only need one app, one running event loop
Development Environment
Windows 10, PyQt5, pyqt5-5.9
EDIT
The problem doesn't seem to be directly related to the menu bar. Even removing the menu bar the issue still occurs. That said, changing from showMaximized() to showFullScreen() does seem to solve the problem.
I no longer believe this is an issue with PyQt5 specifically but rather a problem with the graphics driver. Specifically, if you look at Atlassian's HipChat application it has a similar problem which is documented here:
https://jira.atlassian.com/browse/HCPUB-3177
Some individuals were able to solve the problem by running the application from the command prompt with the addendum "--disable-gpu" but that didn't work for my python application. On the other hand, rolling back the Intel(R) HD Graphics Driver did solve my problem. Version 21.20.16.4627 is the one that seems to be causing problems.
I'm writing a GUI in PyQt4 (and migrating to PyQt5). This is how I start my GUI:
if __name__== '__main__':
app = QApplication(sys.argv)
QApplication.setStyle(QStyleFactory.create('Fusion')) # <- Choose the style
myGUI = MyMainWindow("First GUI")
app.exec_()
Default Styles in PyQt4 :
Apparently, PyQt4 has the following styles:
'Windows'
'WindowsXP'
'WindowsVista'
'Motif'
'CDE'
'Plastique'
'Cleanlooks'
Default Styles in PyQt5 :
PyQt5 has the following styles:
'Windows'
'WindowsXP'
'WindowsVista'
'Fusion'
Custom styles?
None of these styles has proper support for HiDpi displays (4k and the like). For example, scrollbars are too small( see this post: How to resize the scrollbar from a QTextEdit in PyQt?). And I didn't even mention the problems for those people with unsharp eyesight..
Do you know a style (preferably open-source) that provides good support for 4k displays or for people with eyesight problems?
If so, how can one download this style, and install it?
Thank you so much.
I got the answer (or let's say a workaround) through another question:
How to make Icon in QMenu larger (PyQt)?
The most straightforward way to create a new QStyle is deriving it from an existing one. PyQt provides the QProxyStyle class for that purpose. Below is the example that I've also given in the How to make Icon in QMenu larger (PyQt)? question. In this example, a custom QStyle is created (derived from "Fusion" style), and the custom style provides very big icons for the QMenu.
import sys
import os
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
# Create a custom "QProxyStyle" to enlarge the QMenu icons
#-----------------------------------------------------------
class MyProxyStyle(QProxyStyle):
pass
def pixelMetric(self, QStyle_PixelMetric, option=None, widget=None):
if QStyle_PixelMetric == QStyle.PM_SmallIconSize:
return 40
else:
return QProxyStyle.pixelMetric(self, QStyle_PixelMetric, option, widget)
# This is the main window class (with a simple QMenu implemented)
# ------------------------------------------------------------------
class TestWindow(QMainWindow):
def __init__(self):
super(TestWindow, self).__init__()
# 1. Set basic geometry and color.
self.setGeometry(100, 100, 400, 400)
self.setWindowTitle('Hello World')
palette = QPalette()
palette.setColor(QPalette.Window, QColor(200, 200, 200))
self.setPalette(palette)
# 2. Create the central frame.
self.centralFrame = QFrame()
self.centralFrame.setFrameShape(QFrame.NoFrame)
self.setCentralWidget(self.centralFrame)
# 3. Create a menu bar.
myMenuBar = self.menuBar()
fileMenu = myMenuBar.addMenu("&File")
testMenuItem = QAction(QIcon("C:\\my\\path\\myFig.png"), "&Test", self)
testMenuItem.setStatusTip("Test for icon size")
testMenuItem.triggered.connect(lambda: print("Menu item has been clicked!"))
fileMenu.addAction(testMenuItem)
# 4. Show the window.
self.show()
# Start your Qt application based on the new style
#---------------------------------------------------
if __name__== '__main__':
app = QApplication(sys.argv)
myStyle = MyProxyStyle('Fusion') # The proxy style should be based on an existing style,
# like 'Windows', 'Motif', 'Plastique', 'Fusion', ...
app.setStyle(myStyle)
myGUI = TestWindow()
sys.exit(app.exec_())
Just copy-paste the code snippet, and paste it in a *.py file. Of course, you should replace the path to the icon with a valid path on your local computer. Just provide a complete path ("C:..") to be 100% sure that Qt finds the icon drawing.
Try it out, and you should get the following window: