Despite existing, translated texts do not appear in my GUI.
Here is the main.py
from PyQt5 import QtCore
from PyQt5.QtWidgets import QApplication, QWidget, QMainWindow
import sys, os
from view.MainWindow import MainWindow
if __name__=='__main__':
app = QApplication(sys.argv)
mainWindow = MainWindow()
MainWindow.show(mainWindow)
translator = QtCore.QTranslator()
(filepath,filename)=os.path.split(__file__)
trad_path=os.path.join(filepath,'translate','fr_FR.qm')
print (trad_path)
translator.load(trad_path)
app.installTranslator(translator)
sys.exit(app.exec_())
The main.py file is under a src folder alongside a translate folder containing the fr_FR.qm file.
The print (trad_path) shows that the path to the file is correct
Inside , the MainWindow.py file I have a showEvent() function that calls the set_translatable_textes() function
def showEvent(self,ev):
print('in show event')
self.set_translatable_textes()
def set_translatable_textes(self):
self.choose_session_label.setText(
QCoreApplication.translate(
'Main Window','A text that has translation'))
#self.choose_session_label.setText('Untranslated text')
self.edit_button.setText(self.tr('Edit'))
#self.edit_button.setText('Untranslated text')
I try two kinds of translation :
With QCoreApplication.translate()
With tr()
None of them is working. To be sure I call the function, I replace each statements with the commented statement under. They both work.
I am probably doing something wrong but what?
How stupid!
The translator was not ready at the time the MainWindow showed up.
I placed the translator stuff in main before MainWindow.show() and it became fine.
Related
First File first.py
import pyqt5py
ret=pyqt5py.confirm()
print(ret)
Second File Having PYQT5 name: pyqt5py.py
import sys
from PyQt5 import QtWidgets, uic
class Ui(QtWidgets.QDialog):
def __init__(self,button1='Ok',button2='Cancel',text='Are You Sure?'):
super(Ui, self).__init__() # Call the inherited classes __init__ method
uic.loadUi('dialog.ui', self) # Load the .ui file
# Show the GUI
self.pushButton1.clicked.connect(lambda: self.click(1))
self.pushButton2.clicked.connect(lambda: self.click(2))
self.label.setText(text)
self.pushButton1.setText(button1)
self.pushButton2.setText(button2)
self.show()
def click(self,args):
print(self)
return self.sender().text()
app = QtWidgets.QApplication(sys.argv) # Create an instance of QtWidgets.QApplication
def confirm():
def pressed():
return 'clicked'
window = Ui(button1='Ok',button2='Cancel',text='Are You Sure?') # Create an instance of our class
print(window)
window.pushButton1.clicked.connect(pressed)
app.exec_() # Start the application
but i dont know what changes should i do make my first.py to work,i have correctly made the pyqt5 file but i dont know how to add def to call it for confirm
#######################
I Updated My Second File
As suggested by bfris you should rewrite the last lines of pyqt5py.py as follows:
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
window = Ui(button1='Ok',button2='Cancel',text='Are You Sure?')
app.exec_()
That way you can run this file directly for debbugging purposes, but also import it elsewhere.
To use your widget in first.py you need to create an instance of it there.
first.py:
from pyqt5py.py import UI
app = QtWidgets.QApplication(sys.argv)
window = Ui(button1='Ok',button2='Cancel',text='Are You Sure?')
app.exec_()
Usually I use a QDialog within a Qt environment where it is opened from a QMainWindow and also returning which button was clicked to the QMainWindow.
However as I understand you would like to run another program and in between open your UI? I am not experienced doing that but it seems to me that its exec method does exactly that though you should read this discussion about a bug related to it.
Alternatively in first.py you connect the pushbutton's clicked signal to a slot, a function there.
When I design a UI with PyQt5, in Qt Designer it looks like win10 app. But when I start a program in VS Code or just run a file, it looks like in Windows Vista or 7. How to fix that? I haven't changed style in the code
import os
import sys
from PyQt5 import uic
from PyQt5.QtWidgets import QApplication, QMainWindow
class UI(QMainWindow):
def __init__(self):
super().__init__()
uic.loadUi(os.path.join(sys.path[0], 'untitled.ui'), self)
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = UI()
ex.show()
sys.exit(app.exec())
how it looks in designer
how it really looks
You can change the display style by using app.setStyle. To get a list of available styles on your system try this:
from PyQt5.QtWidgets import QStyleFactory
print(QStyleFactory.keys())
on my system I get:
['Breeze', 'Oxygen', 'Windows', 'Fusion']
Probably you'll get difference choices on a Windows box.
To evaluate different styles try:
app.setStyle('<style name here>')
or
app.setStyle(QStyleFactory.create('style name here'))
I just try pyside6 to convert ui files into py files.
When I was using pyside2, I was writing this commande line to convert file:
pyside2-uic MainWindow.ui -o ui_mainwindow.py -x
But with pyside6, it is not working anymore: the "-x" doesn't look necessary. So you have to write:
pyside6-uic MainWindow.ui -o ui_mainwindow.py
BUT, when I run the new file generated, nothing happend. I had a look at the end of file, and it is missing a part there was with pyside2. This part of code is not here anymore:
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())
What I am doing wrong ?
You're not doing anything wrong, that part of the code is added to create an "executable" version of the pyuic file, and its purpose is mainly to test it.
I don't know if the support for -x has been dropped, but that makes sense, and it won't matter a lot anyway: pyuic generated files are not intended to be executed, and should not ever be manually modified, since they should only be used as imports as explained in the official guidelines about using Designer.
The way I do it is import the class the uic created:
from ui_mainwindow import Ui_MainWindow
Then I create a QMainWindow class and instantiate the uic class.
You need to call the setupUi method on the instance.
class UI(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
...
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
win = UI()
win.show()
app.exec()
Now, you can access all the widgets via self.ui:
self.ui.myPushButton.clicked.connect(self.doSomething)
I would like to add a QCheckBox to a QFileDialog. I would like to use the static method QFileDialog.getSaveFileName() to show the dialog.
I have found several similar questions, all in c++:
How to add checkbox to QFileDialog window in QT3?
Adding a widget in QFileDialog
https://www.qtcentre.org/threads/42858-Creating-a-Custom-FileOpen-Dialog
https://forum.qt.io/topic/103964/add-checkbox-to-qfiledialog/7
I did my best to translate these discussions to python, but have not gotten to the solution yet. My code runs, but the checkbox does not show up, even when I use QFileDialog.DontUseNativeDialog.
This is how I am subclassing QFileDialog:
from PyQt5.QtWidgets import QFileDialog
from PyQt5.QtWidgets import QCheckBox
class ChkBxFileDialog(QFileDialog):
def __init__(self, chkBxTitle=""):
super().__init__()
self.setOption(QFileDialog.DontUseNativeDialog)
chkBx = QCheckBox(chkBxTitle)
self.layout().addWidget(chkBx)
#end __init__
#end ChkBxFileDialog
I have run this in two ways.
Option 1 (with extra QFileDialog.DontUseNativeDialog):
import sys
from PyQt5.QtWidgets import QApplication
if __name__ == "__main__":
app = QApplication(sys.argv)
fileDialog = ChkBxFileDialog(chkBxTitle="Chkbx")
fileName = fileDialog.getSaveFileName(filter='*.txt', initialFilter='*.txt',
options=QFileDialog.DontUseNativeDialog)[0]
sys.exit(app.exec_())
Option 2 (without extra QFileDialog.DontUseNativeDialog):
import sys
from PyQt5.QtWidgets import QApplication
if __name__ == "__main__":
app = QApplication(sys.argv)
fileDialog = ChkBxFileDialog(chkBxTitle="Chkbx")
fileName = fileDialog.getSaveFileName(filter='*.txt', initialFilter='*.txt')[0]
sys.exit(app.exec_())
The checkbox doesn't show with either option. Option 1 uses different window styling. Option 2 shows the typical PyQt QFileDialog.
Does anyone know what I am missing?
The problem is that getSaveFileName is a static method so they do not inherit from ChkBxFileDialog and therefore do not have the custom behavior.
There are 2 options:
Don't use getSaveFileName but implement the logic using QFileDialog directly:
import sys
from PyQt5.QtWidgets import QApplication, QCheckBox, QDialog, QFileDialog
class ChkBxFileDialog(QFileDialog):
def __init__(self, chkBxTitle="", filter="*.txt"):
super().__init__(filter=filter)
self.setSupportedSchemes(["file"])
self.setOption(QFileDialog.DontUseNativeDialog)
self.setAcceptMode(QFileDialog.AcceptSave)
self.selectNameFilter("*.txt")
chkBx = QCheckBox(chkBxTitle)
self.layout().addWidget(chkBx)
def main():
app = QApplication(sys.argv)
dialog = ChkBxFileDialog()
if dialog.exec_() == QDialog.Accepted:
filename = dialog.selectedUrls()[0].toLocalFile()
print(filename)
if __name__ == "__main__":
main()
Use some trick to get the QFileDialog instance, such as getting all the topLevels and verifying that it is a QFileDialog.
import sys
from functools import partial
from PyQt5.QtCore import QTimer
from PyQt5.QtWidgets import QApplication, QCheckBox, QDialog, QFileDialog
def add_checkbox(chkBxTitle):
for tl in QApplication.topLevelWidgets():
if isinstance(tl, QFileDialog):
tl.setOption(QFileDialog.DontUseNativeDialog)
chkBx = QCheckBox(chkBxTitle)
tl.layout().addWidget(chkBx)
def main():
app = QApplication(sys.argv)
QTimer.singleShot(1000, partial(add_checkbox, ""))
fileName, _ = QFileDialog.getSaveFileName(
filter="*.txt", initialFilter="*.txt", options=QFileDialog.DontUseNativeDialog
)
if __name__ == "__main__":
main()
I would like to use the static method QFileDialog.getSaveFileName() to show the dialog
That's not possible. The static method as is defined in the C++ code knows nothing about your derived class, so it will create an instance of the base class, which doesn't contain your modifications. You have to explicitly instantiate your derived class, call exec() on the instance, check the return code and possibly call its selectedFiles() method to see what files were selected.
I try to read dataframe from excel file and print it after button click.
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QMessageBox
from PyQt5.QtGui import QIcon
from excel_reading import *
class MyWin(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self):
super().__init__()
self.setupUi(self)
self.pushButton.clicked.connect(self.hello)
def hello(self):
data_input_from_file = QtWidgets.QFileDialog.getOpenFileName(self,'header','filename','Excel (*.xlsx *.xls)')
print(data_input_from_file)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
myapp = MyWin()
myapp.show()
sys.exit(app.exec_())
When I click button, I have such message:
Gtk-Message: 00:03:53.573: GtkDialog mapped without a transient parent. This is discouraged.
('', '')
How should I solve that problem?
I solved the problem:
def hello(self):
data_input_from_file = QtWidgets.QFileDialog.getOpenFileName(self, 'header', 'filename', 'Excel (*.xlsx *.xls)')
print(type(data_input_from_file))
print(data_input_from_file)
print(pd.read_excel(data_input_from_file[0]))
The Gtk warning is just what it is: a warning. You can ignore that. Qt tries to use the system native file dialogs whenever possible, which might result in some warnings in the consolle output.
Your issue is related to something else: there are rare cases for which PyQt functions don't return the same signature as reported in the official Qt (C++) documentation.
QFileDialog static methods is one of such cases, as QFileDialog.getOpenFileName() always returns a tuple: the selected file path and the selected file type filter. This is also clear from the output of your code (which I suppose is caused by cancelling the dialog):
('', '')
The first value is the selected file (in this case, none) and filter (again, none, as there was no selected file).
The solution is to assign two values for what the static returns:
filePath, filters = QtWidgets.QFileDialog.getOpenFileName(
self,'header','filename','Excel (*.xlsx *.xls)')
if filePath:
# do something