I am trying to create a program where the user has three options to answer a question. I used QGridLayout for this but only the last widget added to the QGridLayout is shown.
Expected:
################################
# Text #
################################
########## ########## ##########
#Button 1# #Button 2# #Button 3#
########## ########## ##########
Reality:
##########
#Button 3#
##########
Simplified Python 3 Code (No Text Widget):
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
import sys
QApp = QApplication(sys.argv)
QMWRoot = QMainWindow()
QGLRoot = QGridLayout(QMWRoot)
QMWRoot.setLayout(QGLRoot)
QPB0 = QPushButton('B0x0', QMWRoot)
QGLRoot.addWidget(QPB0, 0, 0)
QPB1 = QPushButton('B0x1', QMWRoot)
QGLRoot.addWidget(QPB1, 0, 1)
QPB2 = QPushButton('B1x0', QMWRoot)
QGLRoot.addWidget(QPB2, 1, 0)
QMWRoot.show()
sys.exit(QApp.exec_())
Original (Unfinished) Python 3 Code:
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
import sys
class Root(QMainWindow):
def __init__(self, QApp):
super().__init__()
self.QApp = QApp
def setupUi(self):
self.setWindowTitle('')
self.QGLRoot = QGridLayout()
self.setLayout(self.QGLRoot)
self.QLBTool = QLabel()
self.QLBTool.setText('Tool')
self.QGLRoot.addWidget(self.QLBTool, 0, 0)
self.QPB0 = QPushButton(self)
self.QPB0.setText('0')
self.QGLRoot.addWidget(self.QPB0, 1, 0)
self.QPB1 = QPushButton(self)
self.QPB1.setText('1')
self.QGLRoot.addWidget(self.QPB1, 1, 1)
self.QPB2 = QPushButton(self)
self.QPB2.setText('2')
self.QGLRoot.addWidget(self.QPB2, 1, 2)
def startUi(self):
self.show()
def updateUi(self):
pass
QApp = QApplication(sys.argv)
App = Root(QApp)
App.setupUi()
App.startUi()
sys.exit(QApp.exec_())
QMainWindow you have a special structure:
So in your case you must establish a centralwidget and there place the layout.
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class Root(QMainWindow):
def __init__(self, QApp):
super().__init__()
self.QApp = QApp
def setupUi(self):
self.setWindowTitle('')
widget = QWidget()
self.setCentralWidget(widget)
self.QGLRoot = QGridLayout()
widget.setLayout(self.QGLRoot)
self.QLBTool = QLabel()
self.QLBTool.setAlignment(Qt.AlignHCenter)
self.QLBTool.setText('Tool')
self.QGLRoot.addWidget(self.QLBTool, 0, 0, 1, 3)
self.QPB0 = QPushButton()
self.QPB0.setText('0')
self.QGLRoot.addWidget(self.QPB0, 1, 0)
self.QPB1 = QPushButton()
self.QPB1.setText('1')
self.QGLRoot.addWidget(self.QPB1, 1, 1)
self.QPB2 = QPushButton()
self.QPB2.setText('2')
self.QGLRoot.addWidget(self.QPB2, 1, 2)
def startUi(self):
self.show()
QApp = QApplication(sys.argv)
App = Root(QApp)
App.setupUi()
App.startUi()
sys.exit(QApp.exec_())
Compact and generalized code:
import sys
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget, \
QGridLayout, QLabel, QPushButton
class Root(QMainWindow):
def __init__(self, QApp):
super().__init__()
self.setupUi()
def setupUi(self):
self.setWindowTitle('')
widget = QWidget()
self.setCentralWidget(widget)
QGLRoot = QGridLayout(widget)
options = ("0", "1", "2")
QLBTool = QLabel('Tool')
QLBTool.setAlignment(Qt.AlignHCenter)
QGLRoot.addWidget(QLBTool, 0, 0, 1, len(options))
for i, option in enumerate(options):
button = QPushButton(option)
QGLRoot.addWidget(button, 1, i)
QApp = QApplication(sys.argv)
App = Root(QApp)
App.show()
sys.exit(QApp.exec_())
Related
I want to be able to detect if the slider has moved to a new position and then do some actions in another function called sl. Here is my code:
import sys
from PyQt5 import QtWidgets
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QApplication, QLabel, QLineEdit, QScrollBar, QMainWindow, QMenu, QWidget, QGridLayout, \
QMessageBox, QListWidget, QPlainTextEdit, QTableWidget, QTableWidgetItem, QHeaderView
from PyQt5.QtWidgets import QMenuBar, QHBoxLayout, QVBoxLayout, QSlider, QPushButton, QDial, QBoxLayout, QSpacerItem
from PyQt5.QtGui import QFont, QColor, QPixmap, QResizeEvent, QPen
import PyQt5.QtGui as QtGui
import PyQt5.QtCore as QtCore
class ControlWidget(QWidget):
def __init__(self):
QWidget.__init__(self)
self.layout = QVBoxLayout()
self.layout.setContentsMargins(10, 10, 10, 10)
widget3 = QLabel("Manual")
big_font = QFont('Arial')
big_font.setPointSize(15)
widget3.setFont(big_font)
self.layout.addWidget(widget3, stretch=1)
widget2 = ManualWidget()
self.layout.addWidget(widget2, stretch=4)
self.setLayout(self.layout)
class ManualWidget(QWidget):
def __init__(self):
QWidget.__init__(self)
self.layout = QHBoxLayout()
right_widget = QWidget()
right_layout = QVBoxLayout()
right_top_widget = QWidget()
self.sld1 = self.slider('V1:', 0, 100)
right_top_layout = QVBoxLayout()
right_top_layout.setContentsMargins(0, 0, 0, 0)
right_top_layout.addWidget(self.sld1, stretch=1)
right_top_widget.setLayout(right_top_layout)
right_layout.addWidget(right_top_widget)
right_widget.setLayout(right_layout)
self.layout.addWidget(right_widget, stretch=1)
self.setLayout(self.layout)
self.layout.addWidget(self.name)
self.layout.addWidget(self.label)
self.layout.addWidget(self.slider)
print(self.sl())
def slider(self, name, low, high, step=10):
self.name = QLabel(str(name))
self.label = QLabel(str(low))
self.slider = QSlider(Qt.Horizontal, self)
self.slider.setMinimum(low)
self.slider.setMaximum(high*step)
self.slider.setValue(low)
self.slider.valueChanged.connect(self.change_value)
self.action = False
self.slider.sliderMoved.connect(self.act1)
def change_value(self):
self.set_point = (float(self.slider.value())) / 10
self.label.setText(str(self.set_point))
def act1(self):
self.action = True
return self.action
def sl(self):
if self.action == True:
x = 3
else:
x = 6
return x
class MainWidget(QWidget):
def __init__(self):
QWidget.__init__(self)
self.layout = QVBoxLayout()
self.layout.setContentsMargins(0, 0, 0, 0)
big_font = QFont('Arial')
big_font.setPointSize(10)
bottom_widget = ControlWidget()
self.layout.addWidget(bottom_widget, stretch=10)
self.setLayout(self.layout)
class Window(QMainWindow):
def __init__(self, widget):
QMainWindow.__init__(self)
self.setWindowTitle("Flow test rig")
self.menu = self.menuBar()
self.setCentralWidget(widget)
self.status = self.statusBar()
widget.parent = self
app = QApplication(sys.argv)
main_widget = MainWidget()
win = Window(main_widget)
win.show()
sys.exit(app.exec_())
I tried to detect it with the act1 function, however, self.action is always False, or when it becomes True, it does not reset to False after the first move of the slider. I appreciate it if someone would help me.
How to set a background colour of text occupied area Only, in QLabel ?
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
class myList(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("Frame Example")
self.myui()
def myui(self):
self.textbox = QLineEdit()
self.label_head = QLabel("Company Name")
self.textbox.setFixedSize(400,30)
self.label_head.setFont(QFont("caliber",12,QFont.Bold))
self.label_head.setAlignment(Qt.AlignCenter)
self.label_head.setStyleSheet("background-color:red;border-radius:5px;padding:2px;")
self.label_head.adjustSize()
self.label_head.setAutoFillBackground(True)
vbox = QVBoxLayout()
vbox.addWidget(self.label_head)
vbox.addWidget(self.textbox)
self.setLayout(vbox)
def main():
myapp = QApplication(sys.argv)
mywin = myList()
mywin.show()
sys.exit(myapp.exec_())
if __name__ == '__main__':
main()
In this code, I need a background color to text area only ( "Company name").
Try it
self.label_head = QLabel("<span style='color: #fff; background-color: #00f'>Company Name</span>")
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
class myList(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("Frame Example")
self.myui()
def myui(self):
self.textbox = QLineEdit()
self.label_head = QLabel("<span style='color: #fff; background-color: #00f'>Company Name</span>") # <---
self.textbox.setFixedSize(400,30)
self.label_head.setFont(QFont("caliber",12,QFont.Bold))
self.label_head.setAlignment(Qt.AlignCenter)
self.label_head.setStyleSheet("background-color:red;border-radius:5px;padding:2px;")
self.label_head.adjustSize()
self.label_head.setAutoFillBackground(True)
vbox = QVBoxLayout()
vbox.addWidget(self.label_head)
vbox.addWidget(self.textbox)
self.setLayout(vbox)
def main():
myapp = QApplication(sys.argv)
mywin = myList()
mywin.show()
sys.exit(myapp.exec_())
if __name__ == '__main__':
main()
I've seen a number of replies on SO regarding this matter but not specifically to QMenu and QToolButton. Would appreciate some pointers on aligning the popup widget to the right side of the button. Here's a basic code I'm working off..
import sys
from PyQt5.QtWidgets import *
class test(QWidget):
def __init__(self):
super().__init__()
self.resize(200, 100)
layout = QHBoxLayout(self)
label = QLabel('Testing QToolButton Popup')
toolbutton = QToolButton()
toolbutton.setPopupMode(QToolButton.InstantPopup)
widget = QWidget()
widgetLayout = QHBoxLayout(widget)
widgetLabel = QLabel('Popup Text')
widgetSpinbox = QSpinBox()
widgetLayout.addWidget(widgetLabel)
widgetLayout.addWidget(widgetSpinbox)
widgetAction = QWidgetAction(toolbutton)
widgetAction.setDefaultWidget(widget)
widgetMenu = QMenu(toolbutton)
widgetMenu.addAction(widgetAction)
toolbutton.setMenu(widgetMenu)
layout.addWidget(label)
layout.addWidget(toolbutton)
if __name__ == '__main__':
app = QApplication(sys.argv)
win = test()
win.show()
sys.exit(app.exec_())
The outcome looks like this:
The Qt developer thought the default position was correct, so if you want to modify the alignment you must move the QMenu as I show below:
import sys
from PyQt5.QtCore import QPoint
from PyQt5.QtWidgets import (
QApplication,
QHBoxLayout,
QLabel,
QMenu,
QSpinBox,
QToolButton,
QWidgetAction,
QWidget,
)
class Menu(QMenu):
def showEvent(self, event):
if self.isVisible():
button = self.parentWidget()
if button is not None:
pos = button.mapToGlobal(button.rect().bottomRight())
self.move(pos - self.rect().topRight())
super().showEvent(event)
class Test(QWidget):
def __init__(self):
super().__init__()
self.resize(200, 100)
layout = QHBoxLayout(self)
label = QLabel("Testing QToolButton Popup")
toolbutton = QToolButton(popupMode=QToolButton.InstantPopup)
widgetLabel = QLabel("Popup Text")
widgetSpinbox = QSpinBox()
widget = QWidget()
widgetLayout = QHBoxLayout(widget)
widgetLayout.addWidget(widgetLabel)
widgetLayout.addWidget(widgetSpinbox)
widgetAction = QWidgetAction(toolbutton)
widgetAction.setDefaultWidget(widget)
widgetMenu = Menu(toolbutton)
widgetMenu.addAction(widgetAction)
toolbutton.setMenu(widgetMenu)
layout.addWidget(label)
layout.addWidget(toolbutton)
if __name__ == "__main__":
app = QApplication(sys.argv)
win = Test()
win.show()
sys.exit(app.exec_())
I'm making a GUI in PyQt5 where there are multiple tabs. In one of the tabs, users select a radio button with what type of data they are entering.
This information changes what buttons are available in other tabs and I'm having trouble getting this information passed from the original tab class. I'd like to see if a radio button is checked from another tab and if it is, enable a button.
I have a function to return a string depending on which radio button is selected, but when I call the getDataType() function from the other tab, I get the error "AttributeError: module 'DataTab' has no attribute 'getDataType.'"
I've tried moving the getDataType() function outside of the DataTab class, but since the radio buttons use "self," I'm not able to access them.
I've also tried making a new class and calling that new class from the function, but then I get stuck on how to get the information to my other tab.
So in this example, once a user selects a radio button in the Data Tab, I want the corresponding push button on the Analysis Tab enabled.
When I uncomment the call to getDataType(), I get the following error: "AttributeError: module 'DataTab' has no attribute 'getDataType'"
from PyQt5.QtWidgets import (QWidget, QVBoxLayout, QLabel, QTableWidget, QTableWidgetItem,
QLineEdit, QFileDialog, QRadioButton, QGroupBox, QPushButton,
QGridLayout, QButtonGroup, QApplication, QAbstractItemView,
QTabWidget)
from PyQt5.QtGui import QIcon
import sys, os
class TabPage(QTabWidget):
def __init__(self):
super().__init__()
self.setStyleSheet('font: 15pt Tw Cen MT')
self.show()
# Creating the tabs here to have a reference
self.tabWidget = QTabWidget()
self.tabWidget.addTab(DataTab(), "Data Input")
self.tabWidget.addTab(AnalysisTab(), "Analysis")
self.layout = QVBoxLayout()
self.layout.addWidget(self.tabWidget)
self.setLayout(self.layout)
# The DataTab class holds all the GUI for the DataTab
class DataTab(QWidget):
def __init__(self):
super().__init__()
self.app = QApplication(sys.argv)
self.layout = QGridLayout()
self.intervalRadioButton = QRadioButton("Interval")
self.ordinalRadioButton = QRadioButton("Ordinal")
self.frequencyRadioButton = QRadioButton("Frequency")
self.submitButton = QPushButton("Submit Data")
self.layout.addWidget(self.intervalRadioButton, 7, 0, 1, 3)
self.layout.addWidget(self.ordinalRadioButton, 8, 0, 1, 3)
self.layout.addWidget(self.frequencyRadioButton, 9, 0, 1, 3)
self.setLayout(self.layout)
self.show()
def getDataType(self):
if self.intervalRadioButton.isChecked():
return "interval"
elif self.ordinalRadioButton.isChecked():
return "ordinal"
elif self.frequencyRadioButton.isChecked():
return "frequency"
class AnalysisTab(QWidget):
def __init__(self):
super().__init__()
self.app = QApplication(sys.argv)
self.createChooseIntervalGroup()
self.createChooseOrdinalGroup()
self.createChooseFrequencyGroup()
self.layout = QGridLayout()
self.layout.addWidget(self.ChooseIntervalGroup, 0, 1)
self.layout.addWidget(self.ChooseOrdinalGroup, 1, 1)
self.layout.addWidget(self.ChooseFrequencyGroup, 2, 1)
self.setLayout(self.layout)
self.show()
# The right side of AnalysisTab containing the buttons for
# analysis
def createChooseIntervalGroup(self):
self.ChooseIntervalGroup = QGroupBox("Tests for Interval Data")
self.analyzeIntervalButton = QPushButton("Analyze")
self.analyzeIntervalButton.setEnabled(False)
# if DataTab.getDataType() != "interval":
# self.analyzeIntervalButton.setEnabled(True)
self.layout = QGridLayout()
self.layout.addWidget(self.analyzeIntervalButton, 1, 1)
self.ChooseIntervalGroup.setLayout(self.layout)
# The right side of AnalysisTab containing the buttons for
# analysis
def createChooseOrdinalGroup(self):
self.ChooseOrdinalGroup = QGroupBox("Tests for Ordinal Data")
self.analyzeOrdinalButton = QPushButton("Analyze")
self.analyzeOrdinalButton.setEnabled(False)
# if DataTab.getDataType() != "ordinal":
# self.analyzeIntervalButton.setEnabled(True)
self.layout = QGridLayout()
self.layout.addWidget(self.analyzeOrdinalButton, 1, 1)
self.ChooseOrdinalGroup.setLayout(self.layout)
# The right side of AnalysisTab containing the buttons for
# analysis
def createChooseFrequencyGroup(self):
self.ChooseFrequencyGroup = QGroupBox("Tests for Frequency Data")
self.analyzeFrequencyButton = QPushButton("Analyze")
self.analyzeFrequencyButton.setEnabled(False)
# if DataTab.getDataType() != "frequency":
# self.analyzeIntervalButton.setEnabled(True)
self.layout = QGridLayout()
self.layout.addWidget(self.analyzeFrequencyButton, 1, 1)
self.ChooseFrequencyGroup.setLayout(self.layout)
def run():
app = QApplication(sys.argv)
tabPage = TabPage()
tabPage.show()
app.exec_()
run()
A possible solution for this case is to use the signals to notify the change of status of the QRadioButton to enable or disable the button.
import sys
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import (
QWidget,
QVBoxLayout,
QRadioButton,
QGroupBox,
QPushButton,
QGridLayout,
QButtonGroup,
QApplication,
QTabWidget,
)
class Widget(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.setStyleSheet("font: 15pt Tw Cen MT")
self.data_tab = DataTab()
self.analysis_tab = AnalysisTab()
self.tabWidget = QTabWidget()
self.tabWidget.addTab(self.data_tab, "Data Input")
self.tabWidget.addTab(self.analysis_tab, "Analysis")
layout = QVBoxLayout(self)
layout.addWidget(self.tabWidget)
self.data_tab.intervalRadioButton.toggled.connect(
self.analysis_tab.analyzeIntervalButton.setEnabled
)
self.data_tab.ordinalRadioButton.toggled.connect(
self.analysis_tab.analyzeOrdinalButton.setEnabled
)
self.data_tab.frequencyRadioButton.toggled.connect(
self.analysis_tab.analyzeFrequencyButton.setEnabled
)
class DataTab(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
layout = QGridLayout(self)
self.intervalRadioButton = QRadioButton("Interval")
self.ordinalRadioButton = QRadioButton("Ordinal")
self.frequencyRadioButton = QRadioButton("Frequency")
self.submitButton = QPushButton("Submit Data")
layout.addWidget(self.intervalRadioButton, 7, 0, 1, 3)
layout.addWidget(self.ordinalRadioButton, 8, 0, 1, 3)
layout.addWidget(self.frequencyRadioButton, 9, 0, 1, 3)
class AnalysisTab(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.createChooseIntervalGroup()
self.createChooseOrdinalGroup()
self.createChooseFrequencyGroup()
layout = QGridLayout(self)
layout.addWidget(self.ChooseIntervalGroup, 0, 1)
layout.addWidget(self.ChooseOrdinalGroup, 1, 1)
layout.addWidget(self.ChooseFrequencyGroup, 2, 1)
def createChooseIntervalGroup(self):
self.ChooseIntervalGroup = QGroupBox("Tests for Interval Data")
self.analyzeIntervalButton = QPushButton("Analyze")
self.analyzeIntervalButton.setEnabled(False)
layout = QGridLayout(self.ChooseIntervalGroup)
layout.addWidget(self.analyzeIntervalButton, 1, 1)
def createChooseOrdinalGroup(self):
self.ChooseOrdinalGroup = QGroupBox("Tests for Ordinal Data")
self.analyzeOrdinalButton = QPushButton("Analyze")
self.analyzeOrdinalButton.setEnabled(False)
layout = QGridLayout(self.ChooseOrdinalGroup)
layout.addWidget(self.analyzeOrdinalButton, 1, 1)
def createChooseFrequencyGroup(self):
self.ChooseFrequencyGroup = QGroupBox("Tests for Frequency Data")
self.analyzeFrequencyButton = QPushButton("Analyze")
self.analyzeFrequencyButton.setEnabled(False)
layout = QGridLayout(self.ChooseFrequencyGroup)
layout.addWidget(self.analyzeFrequencyButton, 1, 1)
def run():
app = QApplication(sys.argv)
tabPage = Widget()
tabPage.show()
app.exec_()
run()
Consider this example:
#!/usr/bin/env python
import sys,os
from PyQt5 import QtCore, QtWidgets, QtGui
from PyQt5.QtCore import Qt
class MainWindow(QtWidgets.QMainWindow):
class ScrollAreaWheel(QtWidgets.QScrollArea): # SO:9475772
def __init__(self, parent=None):
super(MainWindow.ScrollAreaWheel, self).__init__(parent)
self.parent = parent
def wheelEvent(self, event):
print("wheelEvent", event.angleDelta().y())
def __init__(self):
#~ self.do_init = QtCore.QEvent.registerEventType()
QtWidgets.QMainWindow.__init__(self)
self.setMinimumWidth(1000)
self.setMinimumHeight(400)
self.frame1 = QtWidgets.QFrame(self)
self.frame1.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.frame1layout = QtWidgets.QGridLayout(self.frame1)
self.frame1layout.setSpacing(0);
self.frame1layout.setContentsMargins(0,0,0,0);
self.frame1widget = QtWidgets.QWidget()
self.frame1widget.setLayout(QtWidgets.QGridLayout())
self.frame1layout.addWidget(self.frame1widget)
self.frame1scroll = MainWindow.ScrollAreaWheel(self) #QtWidgets.QScrollArea()
self.frame1scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
self.frame1scroll.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
self.frame1widget.layout().addWidget(self.frame1scroll, 0, 0) #, Qt.AlignCenter)
#self.frame1scrolllayout = QtWidgets.QHBoxLayout(self.frame1scroll)
self.frame1scrolllayout = QtWidgets.QGridLayout(self.frame1scroll)
self.frame1scroll.setWidget(self.frame1scrolllayout.widget())
self.frame1scroll.setWidgetResizable(True)
self.frame1scroll.setAlignment(Qt.AlignCenter)
self.frame1label = QtWidgets.QLabel()
self.frame1scrolllayout.addWidget(self.frame1label, 0, 0, Qt.AlignCenter) ##
pixmap = QtGui.QPixmap(200, 100)
pixmap.fill(Qt.red)
self.frame1label.setPixmap(pixmap)
self.frame2 = QtWidgets.QFrame(self)
self.frame2.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.frame2layout = QtWidgets.QHBoxLayout(self.frame2)
self.frame2layout.setSpacing(0);
self.frame2layout.setContentsMargins(0,0,0,0);
self.frame2scroll = QtWidgets.QScrollArea(self)
self.frame2scroll.setWidgetResizable(True)
self.frame2widget = QtWidgets.QWidget()
self.frame2widget.setLayout(QtWidgets.QGridLayout())
self.frame2scroll.setWidget(self.frame2widget)
self.frame2layout.addWidget(self.frame2scroll)
self.mainwid = QtWidgets.QWidget()
self.mainwid.setLayout(QtWidgets.QGridLayout())
self.setCentralWidget(self.mainwid)
self.splitter1 = QtWidgets.QSplitter(Qt.Horizontal)
self.splitter1.addWidget(self.frame1)
self.splitter1.addWidget(self.frame2)
self.splitter1.setSizes([600, 600]); # equal splitter at start
self.mainwid.layout().addWidget(self.splitter1)
self.mainwid.layout().update()
if __name__ == "__main__":
app = QtWidgets.QApplication([])
main = MainWindow()
main.show()
sys.exit(app.exec_())
It generates this (Ubuntu 18.04):
I want to use mousewheel only on the left QScrollArea, for which I've made a separate class. However, its wheelEvent fires only when I'm outside the red box, not when I hover over it. How can I make ScrollAreaWheel.wheelEvent fire even when mouse is over the child label (the red box)?
You are the QLabel placing on top of the QScrollArea instead of placing it inside, visually it is the same but at the level of events it is not.
from PyQt5 import QtCore, QtGui, QtWidgets
class ScrollAreaWheel(QtWidgets.QScrollArea):
def wheelEvent(self, event):
print("wheelEvent", event.angleDelta().y())
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.setMinimumSize(1000, 400)
frame1 = QtWidgets.QFrame(frameShape=QtWidgets.QFrame.StyledPanel)
scrollarea1 = ScrollAreaWheel(widgetResizable=True)
scrollarea1.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
scrollarea1.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
widget1 = QtWidgets.QWidget()
scrollarea1.setWidget(widget1)
label_lay = QtWidgets.QGridLayout(widget1)
lay1 = QtWidgets.QVBoxLayout(frame1)
lay1.addWidget(scrollarea1)
pixmap = QtGui.QPixmap(200, 100)
pixmap.fill(QtCore.Qt.red)
label = QtWidgets.QLabel(pixmap=pixmap)
label_lay.addWidget(label, 0, 0, QtCore.Qt.AlignCenter)
#==============================
frame2 = QtWidgets.QFrame(frameShape=QtWidgets.QFrame.StyledPanel)
scrollarea2 = QtWidgets.QScrollArea(widgetResizable=True)
scrollarea2.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
scrollarea2.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
widget2 = QtWidgets.QWidget()
scrollarea2.setWidget(widget2)
splitter = QtWidgets.QSplitter(QtCore.Qt.Horizontal)
splitter.addWidget(frame1)
splitter.addWidget(frame2)
splitter.setSizes([600, 600])
self.setCentralWidget(splitter)
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.resize(640, 480)
w.show()
sys.exit(app.exec_())