I'm trying to display a folder selection dialog with tkinter in Python, using tkinter.filedialog.askdirectory.
The docs say there is an option called:
mustexist - determines if selection must be an existing directory.
I'd suppose it means by setting mustexist = False, I can enter any arbitrary non-existent path into the bar at the top or the bottom and when hitting "Select folder", it should just return this path without asserting that it exists. Doing so however, an error saying "path does not exist" still appears, preventing dialog return.
Code to reproduce:
import tkinter as tk
from tkinter.filedialog import askdirectory
root = tk.Tk()
root.withdraw()
print(askdirectory(mustexist=False))
(tested on Python3.6 + 3.7 on Windows)
Do I missunderstand something here? Or does it indeed just not work as it should?
I was wondering too and this is the exact behaviour in OSX:
If you don't set it at all, you get an option to create a new folder in form of a "new folder" button in the dialog.
If you set it to True, you don't get that button, but CMD-N still allows you to create a folder.
If you set it to False, you cannot create a folder anymore.
Related
I am using Python v.3.10.7 and tkinter to open a file dialog, and I believe this to be an issue specific to MacOS (using 13.0 (22A380)), however when I am running the following:
from tkinter import filedialog as fd
file = fd.askopenfilename()
print(file)
The console returns the following when the dialog box is opened:
2022-11-14 20:54:12.497 Python[10059:11543274] +[CATransaction synchronize] called within transaction
Just wondering if there is anyway to stop these from being returned- I have also noticed that when moving the dialog box, the line gets spammed constantly.
I am building a very simple python project that will allow the user to read a message in a box and then click OK. This will part of a larger program.
The issue is that when I run it in Spyder, the message box ends up behind all other windows. How do I make it be the focus and open in front of all other windows? I am running a Windows 11 computer.
I call the below function from another python script.
# import libraries
# sys / os to change working directory
import sys
import os
# easygui for message boxes
from easygui import *
# Create function to set working directory
def setworkdir():
uni_code = fileopenbox()
print(uni_code)
# Create Welcome Box
def openMsgBox():
msgbox("Welcome to DocPhoto. Click on Ok to get started")
setworkdir()
The script to call it:
from docFunctions import openMsgBox
openMsgBox()
I have seen answers where the programmer is trying to do this in tkinter, but I'm not using tkinter. Is there a way to do it without tkinter?
Overview:
I need a way to have a printer dialog to print an image (a modern looking one is preferred)
Description:
I tried to find a way to print an image with a printer dialog and I found win32api.ShellExecute(0, "print", "test.jpg", 'None', None, 0)
But to make that work I need a wait after that and when the wait is over the window will close.. and I want it to close ONLY when the user has pressed print or closed the window...
Is there a way of doing that?
and it would be even better if you could link me to another module/way to have that printer dialog maybe a more modern one.. (not the PyQt5 one) because the win32api one looks kinda old school
Edit: So I found this piece of code -
from PySide2.QtWidgets import QApplication, QMainWindow, QAction, QTextEdit
import sys
from PySide2.QtPrintSupport import QPrinter, QPrintPreviewDialog
myapp = QApplication(sys.argv)
window = QMainWindow()
printer = QPrinter(QPrinter.HighResolution)
previewDialog = QPrintPreviewDialog(printer, window)
previewDialog.exec_()
myapp.exec_()
sys.exit()
Source (I have minimized the code above as much as possible): https://codeloop.org/pyside2-print-preview-dialog/
But I don't know how to preview an image (this is using PySide2) please help
Acroding to the document of ShellExecuteA function, nCmdShow parameter is passed via calls to ShellExecute, so I tried every nCmdShow parameters in this function, but it didn't work like you want. It always close the print window after user has printed/closed the window.I suggest you use Print Spooler API Functions to write your own printing interface, so that you can wait for the user's further operation after printing.
import sys
import webbrowser
import hou
from PySide2 import QtCore, QtUiTools, QtWidgets, QtGui
# Calling UI File & Some Modification
class someWidget(QtWidgets.QWidget):
def __init__(self):
super(someWidget,self).__init__()
ui_file = 'C:/Users/XY_Ab/Documents/houdini18.5/Folder_CGI/someUI.ui'
self.ui = QtUiTools.QUiLoader().load(ui_file, parentWidget=self)
self.setParent(hou.qt.mainWindow(), QtCore.Qt.Window)
self.setFixedSize(437, 42)
self.setWindowTitle("Requesting For Help")
window_C = someWidget()
window_C.show()
So, I have created this small script that shows the UI, I have connected this to Houdini Menu Bar. Now The Problem is if I click the menu item multiple times it will create another instance of the same UI & the previous one stays back, What I want is something called "If Window Exist Delete It, Crate New One" sort of thing.
Can someone guide me? I am fairly new to python in Houdini and Qt so a little explanation will be hugely helpful. Also, why can't I use from PySide6 import?? Why do I have to use from PySide2?? Because otherwise Houdini is throwing errors.
For the same thing what used to do in maya is
# Check To See If Window Exists
if cmds.window(winID, exists=True):
cmds.deleteUI(winID)
Trying to do the same thing inside Houdini.
I don't have Maya or Houdini, so I can't help you too much.
According to https://www.sidefx.com/docs/houdini/hom/cb/qt.html
It looks like you can access Houdini's main window. The main reason the window is duplicated or deleted is how python retains the reference to window_C. You might be able to retain the reference to just show the same widget over and over again by accessing the main Houdini window.
In the examples below we are using references a different way. You probably do not need your code that has
self.setParent(hou.qt.mainWindow(), QtCore.Qt.Window)
Create the widget once and keep showing the same widget over and over.
import hou
# Create the widget class
class someWidget(QtWidgets.QWidget):
def __init__(self, parent=None, flags=QtCore.Qt.Window): # Note: added parent as an option
super(someWidget,self).__init__(parent, flags)
...
MAIN_WINDOW = hou.ui.mainQtWindow()
try:
MAIN_WINDOW.window_C.show()
except AttributeError:
# Widget has not been created yet!
# Save the widget reference to an object that will always exist and is accessible
# parent shouldn't really matter, because we are saving the reference to an object
# that will exist the life of the application
MAIN_WINDOW.window_C = someWidget(parent=MAIN_WINDOW)
MAIN_WINDOW.window_C.show()
To delete the previous window and create a new window.
import hou
# Create the widget class
class someWidget(QtWidgets.QWidget):
def __init__(self, parent=None, flags=QtCore.Qt.Window): # Note: added parent as an option
super(someWidget,self).__init__(parent, flags)
...
MAIN_WINDOW = hou.ui.mainQtWindow()
# Hide the previous window
try:
MAIN_WINDOW.window_C.close()
MAIN_WINDOW.window_C.deleteLater() # This is needed if you parent the widget
except AttributeError:
pass
# Create the new Widget and override the previous widget's reference
# Python's garbage collection should automatically delete the previous widget.
# You do not need to have a parent!
# If you do have a parent then deleteLater above is needed!
MAIN_WINDOW.window_C = someWidget() # Note: We do not parent this widget!
MAIN_WINDOW.window_C.show()
Another resource shows you can access the previous widget from the page level variable. https://echopraxia.co.uk/blog/pyqt-in-houdinimaya-basic This is possible, but seems odd to me. The module should only be imported once, so the page level variable "my_window" should never exist. However, it sounds like the Houdini plugin system either reloads the python script or re-runs the import. If that is the case every time you show a new window from the import of the script, you are creating a new window. If the previous window is not closed and deleted properly, Houdini could have an ever growing memory issue.
try:
my_window.close()
except (NameError, Exception):
pass # Normal python would always throw a NameError, because my_window is never defined
my_window = MyWindow()
#This is optional you can resize the window if youd like.
my_window.resize(471,577)
my_window.show()
PySide6
https://www.sidefx.com/docs/houdini/hom/cb/qt.html
The bottom of the page shows how to use PyQt5. The same would apply for PySide6. Houdini just happens to come with PySide2.
I want to start learning Kivy. I have been using Pycharm as my IDE for Python programming. How can I change the default python interpreter to a kivy interpreter so pycharm can recognise kivy codes?
I have installed kivy.app and created symlinks. I have also installed kivy using pip. In my python program, I have been able to successfully import App from kivy.app and it works. But when I write code to design a widget (in this case a Box Layout), Pycharm underlines in red and doesn't execute the code.
The following code works fine:
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
class Widget1(BoxLayout):
pass
class MyApp(App):
def build(self):
return Widget1()
if __name__ == "__main__":
MyApp().run()
But when I write the following code to design the Box Layout, it doesn't work. Pycharm underlines: Widget1, Button, text and Label (Error written is: Unresolved Reference)
<Widget1>
Button:
text: "Please click here"
Label:
text: "Button has not been clicked yet"
If all the codes work, after running, it's supposed to return a Box Layout split into two. One part is a clickable button with "Please click here" written on it and the other part is just a label with "Button has not been clicked yet" written on it. But now when I run, it just returns an empty Box Layout (no label, no button, no text).
Question 2
the Box Layout code (<Widget1>) still doesn't work.
Solution
1) kv Filename
Since you are not using Kivy Builder to load your kv codes/file, therefore you are loading kv codes/file by name convention. Make sure your kv filename is my.kv
Kv language » How to load KV
There are two ways to load Kv code into your application:
By name convention:
Kivy looks for a Kv file with the same name as your App class in
lowercase, minus “App” if it ends with ‘App’ e.g:
MyApp -> my.kv
If this file defines a Root Widget it will be attached to the App’s
root attribute and used as the base of the application widget tree.
By Builder convention: You can tell Kivy to directly load a string or a file. If this string or file defines a root widget, it
will be returned by the method:
Builder.load_file('path/to/file.kv')
or:
Builder.load_string(kv_string)
2) kv Rule Context
In your kv file, add : (full colon) after class rule, <Widget1>
Snippets
<Widget1>:
Kv language » Rule Context
A Kv source constitutes of rules, which are used to describe the
content of a Widget, you can have one root rule, and any number of
class or template rules.
The root rule is declared by declaring the class of your root
widget, without any indentation, followed by : and will be set as the
root attribute of the App instance:
Widget:
A class rule, declared by the name of a widget class between < >
and followed by :, defines how any instance of that class will be
graphically represented:
<MyWidget>:
Rules use indentation for delimitation, as python, indentation should
be of four spaces per level, like the python good practice
recommendations.
Question 1
But when I write code to design a widget (in this case a Box Layout),
Pycharm underlines in red and doesn't execute the code.
Solution
You have to install KV Language auto-completion file.
Download this file, PyCharm_kv_completion.jar.
At bottom-right corner of PyCharm’s Welcome window, click Configure -> Import Settings.
Select the jar file you just downloaded and PyCharm will present a dialog with filetypes ticked. Click OK.
Restart PyCharm for the changes to take effect.