PyQT - Multiple languages QT Designer auto.generated UI - pyqt

I am using PyQt4 and I want to translate my UI created with QT Designer in different languages. I follow some tutorials, but I am not able to apply my translation files.
I created a TS file, edited with QT Linguist and release a QM file. I try to apply it to my app, but it is still in source language.
This is retranslate method:
def retranslateUi(self, CredentialsQT):
CredentialsQT.setWindowTitle(QtGui.QApplication.translate("CredentialsQT", "IngeMaster", None, QtGui.QApplication.UnicodeUTF8))
self.groupBox.setTitle(QtGui.QApplication.translate("CredentialsQT", "Credenciales de usuario", None, QtGui.QApplication.UnicodeUTF8))
self.label.setText(QtGui.QApplication.translate("CredentialsQT", "Usuario:", None, QtGui.QApplication.UnicodeUTF8))
self.label_2.setText(QtGui.QApplication.translate("CredentialsQT", "Contraseña:", None, QtGui.QApplication.UnicodeUTF8))
self.groupBox_2.setTitle(QtGui.QApplication.translate("CredentialsQT", "Lenguaje", None, QtGui.QApplication.UnicodeUTF8))
self.label_3.setText(QtGui.QApplication.translate("CredentialsQT", "Disponibles:", None, QtGui.QApplication.UnicodeUTF8))
self.comboBox.setItemText(0, QtGui.QApplication.translate("CredentialsQT", "Deustch", None, QtGui.QApplication.UnicodeUTF8))
self.comboBox.setItemText(1, QtGui.QApplication.translate("CredentialsQT", "English", None, QtGui.QApplication.UnicodeUTF8))
self.comboBox.setItemText(2, QtGui.QApplication.translate("CredentialsQT", "Español", None, QtGui.QApplication.UnicodeUTF8))
And this is main:
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
archivo = 'Credentials_en.qm'
import os.path
if os.path.exists(archivo):
print "El fichero existe"
else:
print "El fichero no existe"
CredentialsQT = QtGui.QDialog()
ui = Ui_CredentialsQT()
ui.setupUi(CredentialsQT)
#from QtGui import QTranslator
translator=QtCore.QTranslator(app)
if translator.load(archivo, os.getcwd()):
app.installTranslator(translator)
CredentialsQT.show()
sys.exit(app.exec_())
Do you know what I am doing wrong?

There is probably some kind of issue with your code. See how this example works and adapt it to your needs:
#!/usr/bin/env python
#-*- coding:utf-8 -*-
#---------
# IMPORT
#---------
import sys, os, re
import sip
sip.setapi('QString', 2)
sip.setapi('QVariant', 2)
from PyQt4 import QtGui, QtCore
#---------
# DEFINE
#---------
class MyWindow(QtGui.QMainWindow):
def __init__(self, parent=None):
super(MyWindow, self).__init__(parent)
self.languageDirectory = "/usr/share/qt4/translations/"
self.languageLocale = "en"
self.languageTranslator = QtCore.QTranslator()
self.centralWidget = QtGui.QWidget(self)
self.labelLanguageSelect = QtGui.QLabel(self.centralWidget)
self.labelLanguageChange = QtGui.QLabel(self.centralWidget)
self.comboBoxLanguage = QtGui.QComboBox(self.centralWidget)
self.comboBoxLanguage.addItem("en" , "")
for filePath in os.listdir(self.languageDirectory):
fileName = os.path.basename(filePath)
fileMatch = re.match("qt_([a-z]{2,}).qm", fileName)
if fileMatch:
self.comboBoxLanguage.addItem(fileMatch.group(1), filePath)
self.sortFilterProxyModelLanguage = QtGui.QSortFilterProxyModel(self.comboBoxLanguage)
self.sortFilterProxyModelLanguage.setSourceModel(self.comboBoxLanguage.model())
self.comboBoxLanguage.model().setParent(self.sortFilterProxyModelLanguage)
self.comboBoxLanguage.setModel(self.sortFilterProxyModelLanguage)
self.comboBoxLanguage.currentIndexChanged.connect(self.on_comboBoxLanguage_currentIndexChanged)
self.comboBoxLanguage.model().sort(0)
self.buttonBox = QtGui.QDialogButtonBox(self.centralWidget)
self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Yes|QtGui.QDialogButtonBox.Cancel)
self.buttonBox.clicked.connect(self.on_buttonBox_clicked)
self.layoutGrid = QtGui.QGridLayout(self.centralWidget)
self.layoutGrid.addWidget(self.labelLanguageSelect, 0, 0, 1, 1)
self.layoutGrid.addWidget(self.comboBoxLanguage, 0, 1, 1, 1)
self.layoutGrid.addWidget(self.labelLanguageChange, 1, 0, 1, 1)
self.layoutGrid.addWidget(self.buttonBox, 1, 1, 1, 1)
self.setCentralWidget(self.centralWidget)
self.retranslateUi()
self.resetLanguage()
self.updateButtons()
#QtCore.pyqtSlot()
def on_comboBoxLanguage_currentIndexChanged(self):
self.setLanguage()
self.updateButtons()
def changeEvent(self, event):
if event.type() == QtCore.QEvent.LanguageChange:
self.retranslateUi()
super(MyWindow, self).changeEvent(event)
#QtCore.pyqtSlot(QtGui.QAbstractButton)
def on_buttonBox_clicked(self, button):
buttonRole = self.buttonBox.buttonRole(button)
if buttonRole == QtGui.QDialogButtonBox.YesRole:
self.languageLocale = self.comboBoxLanguage.currentText()
self.updateButtons()
elif buttonRole == QtGui.QDialogButtonBox.RejectRole:
self.resetLanguage()
def resetLanguage(self):
index = self.comboBoxLanguage.findText(self.languageLocale)
self.comboBoxLanguage.setCurrentIndex(index)
def setLanguage(self):
app = QtGui.QApplication.instance()
app.removeTranslator(self.languageTranslator)
languageIndex = self.comboBoxLanguage.currentIndex()
languageFileName = self.comboBoxLanguage.itemData(languageIndex, QtCore.Qt.UserRole)
if languageFileName != "en":
languageFilePath = os.path.join(self.languageDirectory, languageFileName)
else:
languageFilePath = ""
self.languageTranslator = QtCore.QTranslator()
if self.languageTranslator.load(languageFilePath):
app.installTranslator(self.languageTranslator)
def updateButtons(self):
state = self.languageLocale != self.comboBoxLanguage.currentText()
self.buttonBox.button(QtGui.QDialogButtonBox.Cancel).setEnabled(state)
self.buttonBox.button(QtGui.QDialogButtonBox.Yes).setEnabled(state)
def retranslateUi(self):
# This text is not included in te .qm file.
# You'll have to create your own .qm file specifying the translation,
# otherwise it won't get translated.
self.labelLanguageSelect.setText(self.tr("Select Language:"))
self.labelLanguageChange.setText(self.tr("Change Language:"))
#---------
# MAIN
#---------
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
app.setApplicationName('MyWindow')
main = MyWindow()
main.resize(333, 111)
main.show()
sys.exit(app.exec_())

I have finally made it to fix it. The problem was the translated words context.
My class was named "Ui_Credentials" and my script "Credentials.py". The .bat that generated python code from QtDesigner automaticaly added "Ui_" prefix to my class.
The solution is to change my script name adding also "Ui_" prefix like "Ui_Credentials.py".
Thanks for the helps!

Related

How to use QtWebEngine createWindow in PyQt5

I am trying to make a window that contains a QWebEngineView. Now I want the browser to be able to handle the create window or _blank type triggers, or specifically to open a URL in a new window when required. In the below code, when there is requirement to create a window by the browser, createwindow() is called, but that doesn't open the window. Please help me with the correct way to open a new window by the browser when required in the below case.
import json
import sys
import os
import time
import json
import sys
import platform
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtWebEngineWidgets import QWebEngineView, QWebEnginePage
from PyQt5.QtWebEngineWidgets import QWebEngineSettings as QWebSettings
from PyQt5.QtGui import QDesktopServices
from PyQt5.QtCore import QUrl
from main_dash import Ui_MainWindow
class MainDashWindow(QMainWindow):
socketSignal = QtCore.pyqtSignal(object) # must be defined in class level
def __init__(self):
QMainWindow.__init__(self)
self.ui = Ui_MainWindow()
# self.ui.setupUi(self)
# ui = Ui_MainWindow()
self.isMax = 0
self.ui.setupUi(self)
def re_setup(self):
self.page = WebEnginePage2()
self.page.Notifications = True
self.ui.full_content_container.hide()
self.page.createWindow = True
self.page.settings().setAttribute(QWebSettings.JavascriptEnabled, True)
self.page.settings().setAttribute(QWebSettings.JavascriptCanOpenWindows, True)
self.page.settings().setAttribute(
QWebSettings.JavascriptCanAccessClipboard, True)
# self.full_content_container is the webengineview in the mainUi file
self.ui.full_content_container.setPage(self.page)
# self.ui.full_content_container.setContextMenuPolicy(Qt.NoContextMenu)
url6 = "...../icons_nec/ui/index.html"
self.ui.full_content_container.setUrl(QtCore.QUrl(url6))
self.ui.full_content_container.loadFinished.connect(
self.on_load_finished)
########################################################################
self.show()
## ==> END ##
def get_path(self, filename):
if hasattr(sys, "_MEIPASS"):
return f'{os.path.join(sys._MEIPASS, filename)}'
else:
return f'{filename}'
def on_load_finished(self):
self.ui.full_content_container.show()
class WebEnginePage2(QWebEnginePage):
def __init__(self, *args, **kwargs):
QWebEnginePage.__init__(self, *args, **kwargs)
self.featurePermissionRequested.connect(
self.onFeaturePermissionRequested)
def onFeaturePermissionRequested(self, url, feature):
self.setFeaturePermission(
url, feature, QWebEnginePage.PermissionGrantedByUser)
def createWindow(self,
wintype: QWebEnginePage.WebWindowType) -> QWebEngineView:
"""Called by Qt when a page wants to create a new tab or window.
In case the user wants to open a resource in a new tab, we use the
createWindow handling of the main page to achieve that.
See WebEngineView.createWindow for details.
"""
return self.page().inspectedPage().view().createWindow(wintype)
# Store external windows.
external_windows = []
def acceptNavigationRequest(self, url, _type, isMainFrame):
print("in navigation")
if _type == QWebEnginePage.NavigationTypeLinkClicked:
w = QWebEngineView()
w.setUrl(url)
w.show()
print("link detected")
# Keep reference to external window, so it isn't cleared up.
self.external_windows.append(w)
return False
# QDesktopServices.openUrl(url)
# elif _type == QWebEnginePage.NavigationType
return super().acceptNavigationRequest(url, _type, isMainFrame)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainDashWindow()
window.re_setup()
sys.exit(app.exec_())
Here is the Ui_MainWindow file, which is being imported above.
I need to figure out with such a scenario how can I implement createWindow() if required by websites.
from PyQt5 import QtWebEngineWidgets
import all_icons_rc
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(1280, 720)
MainWindow.setMinimumSize(QtCore.QSize(1280, 720))
MainWindow.setMaximumSize(QtCore.QSize(1920, 1080))
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.centralwidget)
self.verticalLayout_2.setContentsMargins(0, 0, 0, 0)
self.verticalLayout_2.setSpacing(0)
self.verticalLayout_2.setObjectName("verticalLayout_2")
self.Header = QtWidgets.QFrame(self.centralwidget)
self.Header.setMinimumSize(QtCore.QSize(0, 40))
self.Header.setMaximumSize(QtCore.QSize(16777215, 50))
self.Header.setStyleSheet("background-color: rgb(33, 37, 41);")
self.Header.setFrameShape(QtWidgets.QFrame.NoFrame)
self.Header.setFrameShadow(QtWidgets.QFrame.Raised)
self.Header.setObjectName("Header")
self.horizontalLayout_4 = QtWidgets.QHBoxLayout(self.Header)
self.horizontalLayout_4.setContentsMargins(0, 0, 0, 0)
self.horizontalLayout_4.setSpacing(0)
self.horizontalLayout_4.setObjectName("horizontalLayout_4")
self.frame_2 = QtWidgets.QFrame(self.Header)
self.frame_2.setStyleSheet("")
self.frame_2.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.frame_2.setFrameShadow(QtWidgets.QFrame.Raised)
self.frame_2.setObjectName("frame_2")
self.horizontalLayout_4.addWidget(self.frame_2)
self.frame = QtWidgets.QFrame(self.Header)
self.frame.setMaximumSize(QtCore.QSize(150, 16777215))
self.frame.setStyleSheet("/*background-color: rgb(85, 255, 0);*/")
self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.frame.setFrameShadow(QtWidgets.QFrame.Raised)
self.frame.setObjectName("frame")
self.horizontalLayout = QtWidgets.QHBoxLayout(self.frame)
self.horizontalLayout.setSpacing(15)
self.horizontalLayout.setObjectName("horizontalLayout")
self.minimize_btn = QtWidgets.QPushButton(self.frame)
self.minimize_btn.setText("")
icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap(
":/icons/Icons/icons8_macos_minimize_50px.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.minimize_btn.setIcon(icon)
self.minimize_btn.setIconSize(QtCore.QSize(30, 30))
self.minimize_btn.setFlat(True)
self.minimize_btn.setObjectName("minimize_btn")
self.horizontalLayout.addWidget(self.minimize_btn)
self.maximize_btn = QtWidgets.QPushButton(self.frame)
self.maximize_btn.setText("")
icon1 = QtGui.QIcon()
icon1.addPixmap(QtGui.QPixmap(
":/icons/Icons/icons8_maximize_window_50px.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.maximize_btn.setIcon(icon1)
self.maximize_btn.setIconSize(QtCore.QSize(30, 30))
self.maximize_btn.setFlat(True)
self.maximize_btn.setObjectName("maximize_btn")
self.horizontalLayout.addWidget(self.maximize_btn)
self.close_btn = QtWidgets.QPushButton(self.frame)
self.close_btn.setText("")
icon2 = QtGui.QIcon()
icon2.addPixmap(QtGui.QPixmap(
":/icons/Icons/icons8_Close_50px_2.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.close_btn.setIcon(icon2)
self.close_btn.setIconSize(QtCore.QSize(30, 30))
self.close_btn.setFlat(True)
self.close_btn.setObjectName("close_btn")
self.horizontalLayout.addWidget(self.close_btn)
self.horizontalLayout_4.addWidget(self.frame)
self.verticalLayout_2.addWidget(self.Header)
self.body = QtWidgets.QFrame(self.centralwidget)
self.body.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.body.setFrameShadow(QtWidgets.QFrame.Raised)
self.body.setLineWidth(0)
self.body.setObjectName("body")
self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.body)
self.verticalLayout_3.setContentsMargins(0, 0, 0, 0)
self.verticalLayout_3.setSpacing(0)
self.verticalLayout_3.setObjectName("verticalLayout_3")
self.full_content_container = QtWebEngineWidgets.QWebEngineView(
self.body)#<----This is webengineview
self.full_content_container.setStyleSheet("background-color: rgb(85, 255, 255);\n"
"border:none;")
self.full_content_container.setObjectName("full_content_container")
self.verticalLayout_3.addWidget(self.full_content_container)
self.verticalLayout_2.addWidget(self.body)
MainWindow.setCentralWidget(self.centralwidget)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
For now, just Ignore the icons.
index.html file snippet which is being loaded in webengineview for testing
<!DOCTYPE html>
<html>
<body>
<h1>The a target attribute</h1>
<p>Open link in a new window or tab: Visit PathOr!</p>
</body>
</html>
UPDATE:
Below is an implementaion based on your example code. Everything should work as expected if you completely replace your WebEnginePage2 class with this one:
class WebEnginePage2(QWebEnginePage):
_windows = {}
#classmethod
def newWindow(cls):
window = QWebEngineView()
window.setObjectName(f'window-{id(window)}')
window.setAttribute(QtCore.Qt.WA_DeleteOnClose, True)
window.destroyed.connect(
lambda window: cls._windows.pop(window.objectName(), None))
window.setPage(cls(window))
cls._windows[window.objectName()] = window
return window
def __init__(self, *args, **kwargs):
QWebEnginePage.__init__(self, *args, **kwargs)
self.featurePermissionRequested.connect(
self.onFeaturePermissionRequested)
self.geometryChangeRequested.connect(self.handleGeometryChange)
def handleGeometryChange(self, rect):
view = self.view()
window = QtGui.QWindow.fromWinId(view.winId())
if window is not None:
rect = rect.marginsRemoved(window.frameMargins())
view.resize(rect.size())
view.show()
def createWindow(self, mode):
window = self.newWindow()
if mode != QtWebEngineWidgets.QWebEnginePage.WebDialog:
window.resize(800, 600)
window.show()
return window.page()
def onFeaturePermissionRequested(self, url, feature):
self.setFeaturePermission(
url, feature, QWebEnginePage.PermissionGrantedByUser)
You need to create a new instance of the browser window and keep a reference to it in a window list. It's also important to ensure the window is given an appropriate size, otherwise it won't be visible. For windows opened with javascript, the geometryChangeRequested signal can be used to set the requested size, otherwise a default should be used.
Below is a simple demo that implements the basic features. Hopefully it should be obvious how to adapt this to your own application:
from PyQt5 import QtCore, QtGui, QtWidgets, QtWebEngineWidgets
class Browser(QtWebEngineWidgets.QWebEngineView):
_windows = set()
#classmethod
def _removeWindow(cls, window):
cls._windows.discard(window)
#classmethod
def newWindow(cls):
window = cls()
cls._windows.add(window)
return window
def __init__(self, parent=None):
super().__init__(parent)
self.setAttribute(QtCore.Qt.WA_DeleteOnClose, True)
self.page().geometryChangeRequested.connect(self.handleGeometryChange)
self.page().titleChanged.connect(self.setWindowTitle)
def closeEvent(self, event):
self._removeWindow(self)
event.accept()
def handleGeometryChange(self, rect):
window = QtGui.QWindow.fromWinId(self.winId())
if window is not None:
rect = rect.marginsRemoved(window.frameMargins())
self.resize(rect.size())
self.setFocus()
self.show()
def createWindow(self, mode):
window = self.newWindow()
if mode != QtWebEngineWidgets.QWebEnginePage.WebDialog:
window.resize(800, 600)
window.show()
return window
html = """
<html><head><title>Test Page</title>
<script type="text/javascript"><!--
var count = 0
var url = 'https://www.google.com'
function newWindow() {
count += 1
window.open(url, 'Test' + count, 'width=640,height=480');
}
--></script>
</head>
<body>
<input type="button" value="New Window" onclick="newWindow()" />
<p>Blank</p>
</body>
</html>"""
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
browser = Browser()
browser.setHtml(html)
browser.setGeometry(600, 100, 400, 200)
browser.show()
sys.exit(app.exec_())

Delete a selected QGraphicsPixmapItem in a scene

I'm trying to make a sort of image viewer in which I put a background image ("Affichage du mur" button) and then I load images with the "Importer l'oeuvre" button (you can load as many images you want). It works fine but I would like that we could delete the images ... in fact I would like the image that we delete is the image selected by the user. I can't get the selected image to be deleted with the "Suppression de l'oeuvre" button ... it seems that there is a selectedItems() method but I don't know how to use it in my code. Can you help me please ? Here is a very simplified code of what I am doing :
import os, sys
try : import Image
except ImportError : from PIL import Image
# Imports PyQt5 -----------------------------------------------------------------------
from PyQt5.QtWidgets import QPushButton, QGridLayout, QGraphicsScene, QGraphicsView, \
QGraphicsPixmapItem, QGraphicsItem, QApplication, \
QMainWindow, QFileDialog, QWidget
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QPixmap, QColor, QTransform
# --------------------------------------------------------------------------------------
class TEST(QMainWindow):
def __init__(self):
super(TEST, self).__init__()
self.setWindowTitle('TEST')
self.setGeometry(10, 20, 1280, 760)
self.setMinimumSize(1280, 760)
# ----------------------------------------
self.graphe_vue = MonGraphiqueVueMur()
# ----------------------------------------
bout_visio_mur = QPushButton("Affichage du mur")
bout_visio_mur.setMaximumWidth(230)
bout_visio_mur.setMinimumWidth(230)
bout_visio_oeuvre = QPushButton("Importer l'oeuvre")
bout_visio_oeuvre.setMaximumWidth(230)
bout_visio_oeuvre.setMinimumWidth(230)
bout_supprimer_oeuvre = QPushButton("Suppression de l'oeuvre")
bout_supprimer_oeuvre.setMaximumWidth(230)
bout_supprimer_oeuvre.setMinimumWidth(230)
# ------------------------------------------------------------
bout_visio_mur.clicked.connect(self.graphe_vue.afficher_mur)
bout_visio_oeuvre.clicked.connect(self.graphe_vue.afficher_image_oeuvre)
bout_supprimer_oeuvre.clicked.connect(self.graphe_vue.supprimer_image_oeuvre)
# ------------------------------------------------------------
grid = QGridLayout()
grid.addWidget(self.graphe_vue, 0, 0)
grid.addWidget(bout_visio_mur, 1, 0)
grid.addWidget(bout_visio_oeuvre, 2, 0)
grid.addWidget(bout_supprimer_oeuvre, 3, 0)
widget = QWidget()
widget.setLayout(grid)
self.setCentralWidget(widget)
class MaScene(QGraphicsScene) :
def __init__(self, parent=None) :
super(MaScene, self).__init__(parent)
class MonGraphiquePixmapItemMur(QGraphicsPixmapItem) :
def __init__(self, parent=None):
super(MonGraphiquePixmapItemMur, self).__init__(parent)
class MonGraphiquePixmapItemOeuvre(QGraphicsPixmapItem) :
def __init__(self, parent=None):
super(MonGraphiquePixmapItemOeuvre, self).__init__(parent)
self.setFlag(QGraphicsItem.ItemIsMovable, True)
self.setFlag(QGraphicsItem.ItemIsSelectable, True)
self.setFlag(QGraphicsItem.ItemIsFocusable, True)
self.setAcceptHoverEvents(True)
def hoverEnterEvent(self, event):
print('setAcceptHoverEvents --> Position', event.pos(), type(event.pos()), type(event.pos().x()), type(event.pos().x()))
print("Position X", event.pos().x(), "Position Y", event.pos().y())
class MonGraphiqueVueMur(QGraphicsView) :
backgroundcolor = QColor(100, 100, 100)
def __init__(self, parent=None) :
super(MonGraphiqueVueMur, self).__init__(parent)
self.setBackgroundBrush(self.backgroundcolor)
self.scene = MaScene()
self.setScene(self.scene)
def wheelEvent(self, event):
zoomInFactor = 1.1
zoomOutFactor = 1 / zoomInFactor
self.setTransformationAnchor(QGraphicsView.NoAnchor)
self.setResizeAnchor(QGraphicsView.NoAnchor)
oldPos = self.mapToScene(event.pos())
if event.angleDelta().y() > 0:
zoomFactor = zoomInFactor
else:
zoomFactor = zoomOutFactor
self.scale(zoomFactor, zoomFactor)
newPos = self.mapToScene(event.pos())
delta = newPos - oldPos
self.translate(delta.x(), delta.y())
def afficher_mur(self) :
ouv = QFileDialog.getOpenFileName(self, 'Ouvrir une image', os.path.expanduser('~'), 'Images (*.jpg *.jpeg *.JPG *.JPEG *.png *.gif)')[0]
chemin_fichier = str(ouv)
img_mur = Image.open(chemin_fichier)
self.scene.clear()
self.items().clear()
largeur, hauteur = img_mur.size
pixmap = QPixmap(chemin_fichier)
item = MonGraphiquePixmapItemMur(pixmap)
item.setTransformationMode(Qt.SmoothTransformation)
self.scene.addItem(item)
self.setScene(self.scene)
self.fitInView(item, Qt.KeepAspectRatio)
x, y = 0, 0
self.setSceneRect(-x, -y, largeur, hauteur)
self.centerOn(10, 10)
self.show()
def afficher_image_oeuvre(self) :
ouv = QFileDialog.getOpenFileName(self, 'Ouvrir une image', os.path.expanduser('~'), 'Images (*.jpg *.jpeg *.JPG *.JPEG *.png *.gif)')[0]
chemin_fichier = str(ouv)
pixmap = QPixmap(chemin_fichier)
pixmap = pixmap.scaled(700, 700, Qt.KeepAspectRatio, Qt.SmoothTransformation)
item = MonGraphiquePixmapItemOeuvre(pixmap)
item.setTransformationMode(Qt.SmoothTransformation)
item.setFlag(QGraphicsItem.ItemIsFocusable)
self.scene.addItem(item)
self.setScene(self.scene)
###################################################################################
iteme = self.scene.selectedItems()
print("iteme", iteme) # Return []
###################################################################################
self.show()
def supprimer_image_oeuvre(self) :
import sip
tous_items = list(self.scene.items())
print("len(tous_items)", len(tous_items))
print("tous_items", tous_items)
for i in tous_items :
if str(type(i)) != "<class '__main__.MonGraphiquePixmapItemMur'>" :
self.scene.removeItem(tous_items[0])
sip.delete(tous_items[0])
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = TEST()
ex.show()
sys.exit(app.exec_())
Thanks in advance.
I'd have other questions to ask but we'll see that later.
You just have to cycle through selectedItems(), there's absolutely no need to use the sip module, nor check the class using the string (which is not a good way to do so).
def supprimer_image_oeuvre(self) :
for item in self.scene.selectedItems():
self.scene.removeItem(item)

PyQt5 Retrieve Folder Directory and Set It in lineEdit

Need some advice on how to retrieve the directory path for a selected folder and set it on the LineEdit.
I have the following simple GUI
If I clicked the toolButton (the button inside the red-circle), then a dialog window would pop up. Then we could navigate to select the desired folder. I wish that I could pass the path (in string) to the selected folder to the lineEdit box next to the button, once the user clicks Select Folder. However, I could not figure out how to do that. So far here is my code:
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_TestQFileDialog(object):
def _open_file_dialog(self): # a function to open the dialog window
result = str(QtWidgets.QFileDialog.getExistingDirectory())
print(result)
return result
def setupUi(self, TestQFileDialog):
TestQFileDialog.setObjectName("TestQFileDialog")
TestQFileDialog.resize(240, 320)
self.toolButtonOpenDialog = QtWidgets.QToolButton(TestQFileDialog)
self.toolButtonOpenDialog.setGeometry(QtCore.QRect(210, 10, 25, 19))
self.toolButtonOpenDialog.setObjectName("toolButtonOpenDialog")
directory = self.toolButtonOpenDialog.clicked.connect(self._open_file_dialog)
self.lineEdit = QtWidgets.QLineEdit(TestQFileDialog)
self.lineEdit.setEnabled(False)
self.lineEdit.setGeometry(QtCore.QRect(10, 10, 191, 20))
self.lineEdit.setObjectName("lineEdit")
self.lineEdit.setText('{}'.format(directory))
self.retranslateUi(TestQFileDialog)
QtCore.QMetaObject.connectSlotsByName(TestQFileDialog)
def retranslateUi(self, TestQFileDialog):
_translate = QtCore.QCoreApplication.translate
TestQFileDialog.setWindowTitle(_translate("TestQFileDialog", "Dialog"))
self.toolButtonOpenDialog.setText(_translate("TestQFileDialog", "..."))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
TestQFileDialog = QtWidgets.QDialog()
ui = Ui_TestQFileDialog()
ui.setupUi(TestQFileDialog)
TestQFileDialog.show()
sys.exit(app.exec_())
Tried to include print in the _open_file_dialog function, and it printed the directory path. However, it was not returned and kept in the directory variable.
Any advice will be much appreciated.
Thanks and regards,
Arnold
Found the answer, the .setText method should be included in the _open_file_dialog function.
Therefore, the final code would look like this:
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_TestQFileDialog(object):
def _open_file_dialog(self):
directory = str(QtWidgets.QFileDialog.getExistingDirectory())
self.lineEdit.setText('{}'.format(directory))
def _set_text(self, text):
return text
def setupUi(self, TestQFileDialog):
TestQFileDialog.setObjectName("TestQFileDialog")
TestQFileDialog.resize(240, 320)
self.toolButtonOpenDialog = QtWidgets.QToolButton(TestQFileDialog)
self.toolButtonOpenDialog.setGeometry(QtCore.QRect(210, 10, 25, 19))
self.toolButtonOpenDialog.setObjectName("toolButtonOpenDialog")
self.toolButtonOpenDialog.clicked.connect(self._open_file_dialog)
self.lineEdit = QtWidgets.QLineEdit(TestQFileDialog)
self.lineEdit.setEnabled(False)
self.lineEdit.setGeometry(QtCore.QRect(10, 10, 191, 20))
self.lineEdit.setObjectName("lineEdit")
self.retranslateUi(TestQFileDialog)
QtCore.QMetaObject.connectSlotsByName(TestQFileDialog)
def retranslateUi(self, TestQFileDialog):
_translate = QtCore.QCoreApplication.translate
TestQFileDialog.setWindowTitle(_translate("TestQFileDialog", "Dialog"))
self.toolButtonOpenDialog.setText(_translate("TestQFileDialog", "..."))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
TestQFileDialog = QtWidgets.QDialog()
ui = Ui_TestQFileDialog()
ui.setupUi(TestQFileDialog)
TestQFileDialog.show()
sys.exit(app.exec_())
With QWidget
from PyQt5.QtWidgets import QWidget, QFileDialog,QDialog,QToolButton,QLineEdit,QVBoxLayout ,QGridLayout
class Ui_TestQFileDialog(QWidget):
def __init__(self,parent=None) -> None:
super(Ui_TestQFileDialog,self).__init__(parent)
self.setupUi()
self.show()
def _open_file_dialog(self,lineeditr):
directory = str(QFileDialog.getExistingDirectory())
lineeditr.setText('{}'.format(directory))
def _open_file_dialog1(self):
directory = str(QFileDialog.getExistingDirectory())
self.lineEdit1.setText('{}'.format(directory))
def _set_text(self, text):
return text
def setupUi(self):
# ------------------------- first set ------------------------------------------------------
TestQFileDialog = QDialog()
# TestQFileDialog.setObjectName("TestQFileDialog")
# TestQFileDialog.resize(240, 320)
self.toolButtonOpenDialog = QToolButton(TestQFileDialog)
# self.toolButtonOpenDialog.setGeometry(QtCore.QRect(210, 10, 25, 19))
# self.toolButtonOpenDialog.setObjectName("toolButtonOpenDialog")
self.lineEdit = QLineEdit(TestQFileDialog)
self.lineEdit.setEnabled(False)
# self.lineEdit.setGeometry(QtCore.QRect(10, 10, 191, 20))
# self.lineEdit.setObjectName("lineEdit")
self.lineEdit.textChanged.connect(self.prine_la)
self.toolButtonOpenDialog.clicked.connect(lambda: (self._open_file_dialog(self.lineEdit)))
# ----------------------------- second set --------------------------------------------------------
TestQFileDialog1 = QDialog()
# TestQFileDialog1.setObjectName("TestQFileDialog")
# TestQFileDialog1.resize(240, 320)
self.toolButtonOpenDialog1 = QToolButton(TestQFileDialog1)
# self.toolButtonOpenDialog1.setGeometry(QtCore.QRect(210, 10, 25, 19))
# self.toolButtonOpenDialog1.setObjectName("toolButtonOpenDialog")
self.lineEdit1 = QLineEdit(TestQFileDialog1)
self.lineEdit1.setEnabled(False)
self.lineEdit1.setPlaceholderText("Enter the gain value in between 0.0 to 23.05934920")
# self.lineEdit1.setGeometry(QtCore.QRect(10, 10, 191, 20))
# self.lineEdit1.setObjectName("lineEdit1")
self.toolButtonOpenDialog1.clicked.connect(lambda: (self._open_file_dialog(self.lineEdit1)))
self.retranslateUi(TestQFileDialog,self.toolButtonOpenDialog,"TestQFileDialog","data")
self.retranslateUi(TestQFileDialog1,self.toolButtonOpenDialog1,"TestQFileDialog1","data1")
QtCore.QMetaObject.connectSlotsByName(TestQFileDialog)
QtCore.QMetaObject.connectSlotsByName(TestQFileDialog1)
grid_layout = QGridLayout()
grid_layout.addWidget(self.lineEdit,0,0)
grid_layout.addWidget(self.toolButtonOpenDialog,0,1)
grid_layout.addWidget(self.lineEdit1,1,0)
grid_layout.addWidget(self.toolButtonOpenDialog1,1,1)
ve_box= QVBoxLayout()
# ve_box.addWidget(self.lineEdit)
# ve_box.addWidget(self.toolButtonOpenDialog)
# ve_box.addWidget(self.lineEdit1)
# ve_box.addWidget(self.toolButtonOpenDialog1)
ve_box.addLayout(grid_layout)
self.setLayout(ve_box)
def prine_la(self):
print(self.lineEdit.text())
def retranslateUi(self, TestQFileDialog,tool,dialogue:str,d: str):
_translate = QtCore.QCoreApplication.translate
TestQFileDialog.setWindowTitle(_translate(dialogue, d))
tool.setText(_translate(dialogue, "..."))
print("ANR .S")
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
ui = Ui_TestQFileDialog()
sys.exit(app.exec_())

pyqt adding a widget to a QListWidget

hi i created 2 files from qtdesigner and i created a new file with a class where i want to use these UIs that i created.
this is the file creating the QListWidget
from PyQt4 import QtCore, QtGui
try:
_fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
_fromUtf8 = lambda s: s
class Ui_main_Dialog_lists(object):
def setupUi(self, main_Dialog_lists):
main_Dialog_lists.setObjectName(_fromUtf8("main_Dialog_lists"))
main_Dialog_lists.resize(590, 521)
self.main_verticalLayout = QtGui.QVBoxLayout(main_Dialog_lists)
self.main_verticalLayout.setObjectName(_fromUtf8("main_verticalLayout"))
self.horizontalLayout = QtGui.QHBoxLayout()
self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout"))
self.listWidget_nodes = QtGui.QListWidget(main_Dialog_lists)
self.listWidget_nodes.setObjectName(_fromUtf8("listWidget_nodes"))
self.horizontalLayout.addWidget(self.listWidget_nodes)
self.label_arrow = QtGui.QLabel(main_Dialog_lists)
self.label_arrow.setObjectName(_fromUtf8("label_arrow"))
self.horizontalLayout.addWidget(self.label_arrow)
self.listWidget_nodes_to_render = QtGui.QListWidget(main_Dialog_lists)
self.listWidget_nodes_to_render.setObjectName(_fromUtf8("listWidget_nodes_to_render"))
self.horizontalLayout.addWidget(self.listWidget_nodes_to_render)
self.main_verticalLayout.addLayout(self.horizontalLayout)
self.retranslateUi(main_Dialog_lists)
QtCore.QMetaObject.connectSlotsByName(main_Dialog_lists)
def retranslateUi(self, main_Dialog_lists):
main_Dialog_lists.setWindowTitle(QtGui.QApplication.translate("main_Dialog_lists", "Dialog", None, QtGui.QApplication.UnicodeUTF8))
self.label_arrow.setText(QtGui.QApplication.translate("main_Dialog_lists", ">", None, QtGui.QApplication.UnicodeUTF8))
this is the class creating the widget i want to insert into the rows of the QListWidget
from PyQt4 import QtCore, QtGui
try:
_fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
_fromUtf8 = lambda s: s
class Ui_Frame_nodes(object):
def setupUi(self, Frame_nodes):
Frame_nodes.setObjectName(_fromUtf8("Frame_nodes"))
Frame_nodes.resize(508, 128)
Frame_nodes.setFrameShape(QtGui.QFrame.StyledPanel)
Frame_nodes.setFrameShadow(QtGui.QFrame.Raised)
self.verticalLayout_2 = QtGui.QVBoxLayout(Frame_nodes)
self.verticalLayout_2.setObjectName(_fromUtf8("verticalLayout_2"))
self.horizontalLayout_names = QtGui.QHBoxLayout()
self.horizontalLayout_names.setObjectName(_fromUtf8("horizontalLayout_names"))
self.label_node = QtGui.QLabel(Frame_nodes)
self.label_node.setObjectName(_fromUtf8("label_node"))
self.horizontalLayout_names.addWidget(self.label_node)
self.label_name_start = QtGui.QLabel(Frame_nodes)
self.label_name_start.setObjectName(_fromUtf8("label_name_start"))
self.horizontalLayout_names.addWidget(self.label_name_start)
self.label_name_end = QtGui.QLabel(Frame_nodes)
self.label_name_end.setObjectName(_fromUtf8("label_name_end"))
self.horizontalLayout_names.addWidget(self.label_name_end)
self.label_name_inter = QtGui.QLabel(Frame_nodes)
self.label_name_inter.setObjectName(_fromUtf8("label_name_inter"))
self.horizontalLayout_names.addWidget(self.label_name_inter)
self.verticalLayout_2.addLayout(self.horizontalLayout_names)
self.horizontalLayout_Inputs = QtGui.QHBoxLayout()
self.horizontalLayout_Inputs.setObjectName(_fromUtf8("horizontalLayout_Inputs"))
self.label_node_name = QtGui.QLabel(Frame_nodes)
self.label_node_name.setObjectName(_fromUtf8("label_node_name"))
self.horizontalLayout_Inputs.addWidget(self.label_node_name)
self.lineEdit_node_start = QtGui.QLineEdit(Frame_nodes)
self.lineEdit_node_start.setObjectName(_fromUtf8("lineEdit_node_start"))
self.horizontalLayout_Inputs.addWidget(self.lineEdit_node_start)
self.lineEdit = QtGui.QLineEdit(Frame_nodes)
self.lineEdit.setObjectName(_fromUtf8("lineEdit"))
self.horizontalLayout_Inputs.addWidget(self.lineEdit)
self.lineEdit_3 = QtGui.QLineEdit(Frame_nodes)
self.lineEdit_3.setObjectName(_fromUtf8("lineEdit_3"))
self.horizontalLayout_Inputs.addWidget(self.lineEdit_3)
self.verticalLayout_2.addLayout(self.horizontalLayout_Inputs)
self.retranslateUi(Frame_nodes)
QtCore.QMetaObject.connectSlotsByName(Frame_nodes)
def retranslateUi(self, Frame_nodes):
Frame_nodes.setWindowTitle(QtGui.QApplication.translate("Frame_nodes", "Frame", None, QtGui.QApplication.UnicodeUTF8))
self.label_node.setText(QtGui.QApplication.translate("Frame_nodes", "Node", None, QtGui.QApplication.UnicodeUTF8))
self.label_name_start.setText(QtGui.QApplication.translate("Frame_nodes", "Start", None, QtGui.QApplication.UnicodeUTF8))
self.label_name_end.setText(QtGui.QApplication.translate("Frame_nodes", "End", None, QtGui.QApplication.UnicodeUTF8))
self.label_name_inter.setText(QtGui.QApplication.translate("Frame_nodes", "Inter", None, QtGui.QApplication.UnicodeUTF8))
self.label_node_name.setText(QtGui.QApplication.translate("Frame_nodes", "Node Name", None, QtGui.QApplication.UnicodeUTF8))
after compiling the 2 .ui files i created this file and i am trying to use them, so i can put one inside the other.
import lists
import nodes
from PyQt4 import QtCore, QtGui
import sys
class Master(QtGui.QFrame, QtGui.QWidget, nodes.Ui_Frame_nodes):
def __init__(self):
QtGui.QWidget.__init__(self)
QtGui.QFrame.__init__(self)
self.ui = lists.Ui_main_Dialog_lists()
self.ui.setupUi(self)
for i in range(2):
item_widget = nodes.Ui_Frame_nodes()
qframe = QtGui.QFrame()
item_widget.setupUi(qframe)
wid2 = QtGui.QListWidgetItem()
self.ui.listWidget_nodes.addItem(wid2)
#here is where the script doesnt like it
self.ui.listWidget_nodes.setItemWidget(wid2, item_widget)
app = QtGui.QApplication(sys.argv)
m = Master()
m.show()
app.exec_()
but i cant make it on the setItemWidget i get an error saying
TypeError: QListWidget.setItemWidget(QListWidgetItem, QWidget): argument 2 has unexpected type 'Ui_Frame_nodes'
this is my first time trying to put a widget inside another i am not sure if i am doing it properly.
thanks guys
and here is an image of the UIs
https://dl.dropboxusercontent.com/u/14346803/ui_qt_designer.png
Your problem might be that you haven't setup nodes correctly. I think what's happening is its trying to initialise as a python object (not Qt). I can't currently test this.
You probably need something like:
class CustomNodes(QWidget):
def __init__(self, parent=None):
super(CustomNodes, self).__init__(parent)
self.ui = nodes.Ui_Frame_nodes()
self.ui.setupUi(self)
Then use:
item_widget = CustomNodes(qframe)
self.ui.listWidget_nodes.setItemWidget(wid2, item_widget)
Please note: I haven't tested this code.

Make a choice with a ComboBox, PyQT

how are you ?
I just to create a programme wherein a propose a choice with Combobox.
For exemple, if you choice a item in a ComboBox, it will be write in a Spinbox.
But my probléme is that, to wirte in a third Spinbox without create a new Combobox.
Hope you understand
Check it out :)
`
# -*- coding: utf-8 -*-
import sys
from PyQt4.QtCore import Qt
from PyQt4.QtGui import (QApplication, QWidget, QVBoxLayout, QSpinBox, QComboBox)
class Widget(QWidget):
def __init__(self):
super(Widget, self).__init__()
self.layout = QVBoxLayout(self)
self.spin = QSpinBox(self)
self.spin2 = QSpinBox(self)
self.spin3 = QSpinBox(self)
self.combo = QComboBox(self)
self.combo2 = QComboBox(self)
self.layout.addWidget(self.spin)
self.layout.addWidget(self.spin2)
self.layout.addWidget(self.spin3)
self.layout.addWidget(self.combo)
self.layout.addWidget(self.combo2)
self.combo.currentIndexChanged['QString'].connect(self.on_combo_changed)
self.combo2.currentIndexChanged['QString'].connect(self.changed)
self.data = {"HANDSET1": 5,"HANDSET": 6, "HANDFREE": 10, "CAR KIT": 15, "RSM": 20}
self.dodo = {"HANDSET1": 44, "HANDSET": 76, "HANDFREE": 1, "CAR KIT": 7, "RSM": 0}
self.coco = {"HANDSET1": 0, "HANDSET": 7, "HANDFREE": 11, "CAR KIT": 77, "RSM": 10} # How to put this function, without create a other ComboBox ?
self.combo.addItems(self.data.keys())
self.combo2.addItems(self.dodo.keys())
def on_combo_changed(self, txt):
self.spin.setValue(self.data[unicode(txt)])
def changed(self, txt):
self.spin2.setValue(self.coco[unicode(txt)])
if __name__ == '__main__':
app = QApplication([])
w = Widget()
w.show()
sys.exit(app.exec_())
`

Resources