QScrollArea do not resize according to set size policy - resize

I am not able to use the whole QDialog space for my QScrollArea. I set the QSizePolicy and setWidgetResizeable(true) , but with no results.
from PySide6 import QtWidgets, QtCore
from PySide6.QtCore import Qt
import sys
app = QtWidgets.QApplication(sys.argv)
dialog = QtWidgets.QDialog()
scrollArea = QtWidgets.QScrollArea()
scrollArea.setWidgetResizable(True)
scrollArea.setSizePolicy(QtWidgets.QSizePolicy.Policy.Maximum,QtWidgets.QSizePolicy.Policy.Maximum)
layout = QtWidgets.QVBoxLayout()
layout.addWidget(scrollArea, alignment=Qt.AlignCenter)
dialog.setLayout(layout)
dialog.show()
sys.exit(app.exec())
The QScrollArea do not want to resize to whole QDialog.

Related

How to apply CSS color filter on Folium map tiles

I want to create a dark mode based on Google Maps tiles in Folium. However, as Google is not provided dark mode tiles, a simple workaround seems to be applying a color filter to tiles. A similar plugin for Leaflet is introduced here.
How can I reach a similar result in Folium? Is it possible by executing javascript through the runJavaScript() method (similar to what was done here)?
A minimal Foilium map embedded in PyQt5 is also provided.
import io
import folium
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QMainWindow
from PyQt5.QtWebEngineWidgets import QWebEngineView
class Window(QMainWindow):
def __init__(self):
super().__init__()
self.m = folium.Map(
zoom_start = 18,
location = (41.8828, 12.4761),
control_scale=True,
tiles = None
)
folium.raster_layers.TileLayer(
tiles='http://mt1.google.com/vt/lyrs=m&h1=p1Z&x={x}&y={y}&z={z}',
name='Standard Roadmap',
attr = 'Google Map',
).add_to(self.m)
folium.LayerControl().add_to(self.m)
self.data = io.BytesIO()
self.m.save(self.data, close_file=False)
widget=QWidget()
vbox = QVBoxLayout()
self.webView = QWebEngineView()
self.webView.setHtml(self.data.getvalue().decode())
self.webView.setContextMenuPolicy(Qt.NoContextMenu)
vbox.addWidget(self.webView)
widget.setLayout(vbox)
self.setCentralWidget(widget)
self.setWindowTitle("App")
self.setMinimumSize(1000, 600)
self.showMaximized()
App = QApplication([])
window = Window()
App.exec()

How do I prevent the QPushButton.clicked from the widget from executing when I'm in MainWindow pyqt5?

I set the printInWidget clicked method for the btnprint button in widget1. But I want to replace that command in MainWindow with command printInMain by code: self.wid.btnprint.clicked.connect(self.printInMain). I don't know why it does both commands in MainWindow. Please help me make the command printInWidget not execute when running MainWidow.
Sorry everyone (English is not my native language and I only approached pyqt5 for a few months by teaching myself).
when I click button "printText"
my code:
mainwindow.py
from PyQt5 import QtWidgets
from PyQt5.QtWidgets import QMainWindow, QApplication, QPushButton, QTextEdit, QGridLayout, QVBoxLayout, QFileDialog,QHBoxLayout,QSpacerItem,QSizePolicy
from PyQt5 import uic, QtCore
import sys
from widget1 import *
class UI(QMainWindow):
def __init__(self):
super(UI, self).__init__()
uic.loadUi("MainWindow.ui", self)
self.wid = widget1()
self.verticalLayout.addWidget(self.wid)
self.wid.btnprint.clicked.connect(self.printInMain)
# I want to override method of button printText
def printInMain(self):
self.wid.labelB.setText('New text (method in Main)')
if __name__ == '__main__':
app = QApplication(sys.argv)
window = UI()
window.show()
app.exec_()
widget1.py
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QMainWindow
from PyQt5.QtGui import QIcon
from PyQt5 import uic
class widget1(QWidget):
def __init__(self):
super().__init__()
uic.loadUi('widget1.ui',self)
self.btnprint.clicked.connect(self.printInwidget)
def printInwidget(self):
self.labelA.setText('Hello World (Method in Widget)')
if __name__ == '__main__':
app = QApplication(sys.argv)
Main = QMainWindow()
widget = widget1()
widget.show()
sys.exit(app.exec_())
You need to disconnect. If you want to use the initial behaviour again you need to connect the signal to the slot again. I would suggest creating a reconnect() function that will do that for you if you decide to do the whole thing many times.
Here is an example.
More info can be found in the official QObject documentation (look for bool QObject::disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)).
Also try to provide full code or at least a minimal working example. What you have posted right now cannot work due to missing dependencies and a UI file.

How to embed an URxvt terminal in a Pyqt5 GUI?

I have constructed a GUI in QtChooser and the code for it is written in PyQt5. I have a total of 7 tabs in the GUI, each of which are defined in the QMainWindow class of my code. These definitions contain the codes for each TextEdit, LineEdit, PushButtons, RadioButtons, etc.
However, in one the the tabs, I want to embed an external terminal which will open when a particular PushButton is clicked within that tab. I was able to open the Urxvt terminal when the RadioButton is toggled. The issue I'm facing now is to open the terminal specifically in the area of the TextEdit. This is how the original GUI (built in the QtDesigner looks like. I need the terminal to open in the TextEdit below the Output label. But, this is how the terminal opens in the GUI when the code is run
This is a part of the updated code:
from PyQt5 import QtCore, QtGui, QtWidgets, uic
from PyQt5.QtGui import QPixmap
from PyQt5.QtWidgets import QApplication, QMainWindow, QLabel, QPushButton, QMessageBox, QAction
from PyQt5.QtCore import QDate, QTime, QDateTime, Qt
import sys
import platform
import os
import subprocess
import time
import re
import textwrap
class EmbTerminal(QtWidgets.QWidget):
def __init__(self, parent=None):
super(EmbTerminal, self).__init__()
self.process = QtCore.QProcess(self)
self.terminal = QtWidgets.QWidget(self)
layout = QtWidgets.QVBoxLayout(self)
layout.addWidget(self.terminal)
# Works also with urxvt:
self.process.start('urxvt',['-embed', str(int(self.winId())), '-bg', '#000000', '-fg', '#ffffff'])
self.setFixedSize(539, 308)
class Ui_Dialog(QtWidgets.QMainWindow):
def __init__(self):
super(Ui_Dialog, self).__init__()
#Load GUI from QT5 Designer
uic.loadUi("S1_mainwindow.ui", self)
def openTerminalCheckBox (self):
if self.openTerminalRMachineRadioButton.isChecked():
status = True
self.commandLineRemoteCommandRMachineLineEdit.setDisabled(True)
self.commandlineRemoteCommandRMachineLabel.setDisabled(True)
self.executeRemoteCommandRMachinePushButton.setDisabled(True)
self.remoteMachineOutputLabel.setText("Terminal")
self.outputRMachineTextEdit = QtWidgets.QTabWidget()
self.gridLayout_6.addWidget(self.outputRMachineTextEdit)
self.outputRMachineTextEdit.addTab(EmbTerminal(), "EmbTerminal")
else:
status = False
app = QtWidgets.QApplication(sys.argv) # Create an instance of QtWidgets.QApplication
window = Ui_Dialog()
main = mainWindow()
main.show() # Create an instance of our class
app.exec_()
I need to open the terminal specifically in the QTextEdit which is already been defined in that tab. Do you guys have any suggestions/input?

Using a search bar to find items in a list

I want to use a line edit as a search bar in order to find items in a Qlistwidget. I also want the qlistwidget to scroll up/down (in search) as text is being changed in the line edit.
import sys
from PyQt5 import QtWidgets
from PyQt5.QtWidgets import QGridLayout, QWidget, QListWidget, QLineEdit
class Window(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
centralWidget = QWidget()
self.setCentralWidget(centralWidget)
self.ListBox = QListWidget()
self.ListBox.insertItem(0,'Temperature')
self.ListBox.insertItem(1,'Mass')
self.ListBox.insertItem(2,'Length')
self.ListBox.insertItem(3,'Height')
self.ListBox.insertItem(4,'Width')
self.ListBox.insertItem(5,'Volume')
self.ListBox.insertItem(6,'Surface_Area')
self.ListBox.insertItem(7,'Material')
self.ListBox.insertItem(8,'Location')
self.ListBox.insertItem(9,'Strength')
self.ListBox.insertItem(10,'Color')
self.Search_Bar = QLineEdit()
layout = QGridLayout(centralWidget)
layout.addWidget(self.ListBox)
layout.addWidget(self.Search_Bar)
self.Search_Bar.textChanged.connect(self.Search)
def Search(self):
if self.Search_Bar.text() == 'Strength':
pass
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
window = Window()
window.show()
sys.exit(app.exec_())
The internally implemented match function provided by all Qt item models is usually faster than cycling through the list via Python.
def Search(self, text):
model = self.ListBox.model()
match = model.match(
model.index(0, self.ListBox.modelColumn()),
QtCore.Qt.DisplayRole,
text,
hits=1,
flags=QtCore.Qt.MatchStartsWith)
if match:
self.ListBox.setCurrentIndex(match[0])
This will automatically select and scroll to the first item found (if any).

matplotlib and transparency figure

I am working with the matplotlib library and PyQt5 with Python 3.6. I add a figure in a window I create, and I wish to set transparent the background of this figure because I add an image to the background of the window. But, the figure is not really transparent, it duplicates the background image of the window.
For example, someone deals with the same problem two years ago :
matplotlib and pyqt4 transparent background
Here is a working example (with a background which is black but the figure is not black) :
import sys, os
from PyQt5.QtCore import Qt
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
import matplotlib
matplotlib.use('Qt5Agg') # Make sure that we are using QT5
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar
from matplotlib.figure import Figure
import matplotlib.pyplot as plt
class SecondWindow(QWidget):
def __init__(self, parent=None):
super(SecondWindow, self).__init__(parent)
self.setupUi(self)
def setupUi(self, Form):
# WINDOW SETTINGS
Form.setWindowTitle('Hello')
self.p = QPalette()
self.pixmap = QPixmap(os.getcwd() + "/logo.png").scaled(self.size(), Qt.IgnoreAspectRatio, Qt.SmoothTransformation)
self.p.setBrush(QPalette.Background, QBrush(self.pixmap))
self.setPalette(self.p)
# CREATE FIGURE AND SETTINGS
self.figure = plt.figure()
self.figure.patch.set_facecolor('None')
self.figure.patch.set_alpha(0)
self.canvas = FigureCanvas(self.figure)
self.axes = self.figure.add_subplot(111)
# WINDOW LAYOUT (with H1 and H2)
self.setLayout(QVBoxLayout())
self.layout().addWidget(self.canvas,1)
self.layout().setContentsMargins(50, 50, 50, 50)
if __name__ == '__main__':
app = QApplication(sys.argv)
form = SecondWindow()
form.show()
sys.exit(app.exec_())
I search for answer during long hours but didn't find a solution yet. Thanks for any help you can bring !
Operating System: Windows 7 Pro
Matplotlib Version: 2.0.2 (installed via Anaconda, conda install matplotlib --channel conda-forge)
Python Version: Python 3.6
Anaconda 3
The problem occurs because the background image is set as a palette to the widget. This causes the canvas to inherit the palette and hence the canvas will also have the image as background, somehow overlaying the widget's background.
A solution would be to set the background of the canvas transparent. An easy way to do so are style sheets.
self.canvas.setStyleSheet("background-color:transparent;")
Note that this is not the same as setting the patches' facecolor to none. The figure has a background, which is controlled inside matplotlib, but the canvas, being a PyQt object also has a background.
Complete example:
import sys, os
from PyQt4.QtCore import Qt
from PyQt4.QtGui import *
import matplotlib
matplotlib.use('Qt4Agg')
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt4agg import NavigationToolbar2QT as NavigationToolbar
from matplotlib.figure import Figure
import matplotlib.pyplot as plt
plt.rcParams['xtick.color'] ="w"
plt.rcParams['ytick.color'] ="w"
plt.rcParams['font.size'] = 14
class SecondWindow(QWidget):
def __init__(self, parent=None):
super(SecondWindow, self).__init__(parent)
# CREATE FIGURE AND SETTINGS
self.figure = plt.figure()
self.figure.patch.set_facecolor("None")
self.canvas = FigureCanvas(self.figure)
self.axes = self.figure.add_subplot(111)
self.axes.patch.set_alpha(0.5)
###### Make the background of the canvas transparent
self.canvas.setStyleSheet("background-color:transparent;")
self.p = QPalette()
self.p.setBrush(QPalette.Background, QBrush(QPixmap("house.png")))
self.setPalette(self.p)
self.setLayout(QVBoxLayout())
self.layout().addWidget(self.canvas,1)
self.layout().setContentsMargins(50, 50, 50, 50)
if __name__ == '__main__':
app = QApplication(sys.argv)
form = SecondWindow()
form.show()
sys.exit(app.exec_())
which might then look like