I'm trying to send variables from a dialog back to the Main Window. However, so far I have only been able to pass the default values. My code looks like this:
class OptionsDialog(QDialog):
def __init__(self, parent=None):
super().__init__(parent)
self.ui = Ui_Advanced_Options()
self.ui.setupUi(self)
self.ui.buttonbox_options.accepted.connect(self.Get_Data)
def Get_Data(self):
self.value = self.ui.sellingSpin.value()
return self.value
class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self, *args, obj=None, **kwargs):
super(MainWindow, self).__init__(*args, **kwargs)
"""data about MainWindow"""
def get_input_data(self):
Options = OptionsDialog(self)
self.value = Options.Get_Data()
print(self.value) # this is just an example to see what variable I got
In the dialog I count with many spinboxes. Since the default value is 1, I always get 1. No matter if I had changed it before or not.
Related
I have a Main window that has a settings window that pops out. I want to be able to change one of the settings and it affects the Main window
So far I have
mainwindow.py (the function I want to run to make a frame visible)
class MainWindow(QMainWindow):
def __init__(self, *args, **kwargs):
super(MainWindow, self).__init__(*args, **kwargs)
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
self.ui.button_open_settings.clicked.connect
(self.open_settings)
def open_settings(self):
self.settings_window = settings.MainWindow_settings(self)
self.settings_window.show()
def set_toggle_vis(self, toggle):
self.ui.frame_toggle_list.setVisible(toggle)
settings window.py
class MainWindow_settings(QMainWindow):
def __init__(self, *args, **kwargs):
super(MainWindow_settings, self).__init__(*args,**kwargs)
self.ui = settings_ui.Ui_Form()
self.ui.setupUi(self)
def change_toggle(self):
toggle_enabled = 1
from mainwindow import MainWindow
MWind = MainWindow()
MWind.set_toggle_vis(toggle_enabled)
This kinda works, but it doesn't set the visibility of the frame to 1 as it would if I ran it from the mainwindow, it created a whole new main window, so now 2 are open.
How do I get it to refresh the mainwindow rather than opening a new one?
Answering my own question (with the help of musicamante)
Instead of calling the function I use pyqtSignals to send a signal
class MainWindow(QMainWindow):
def __init__(self, *args, **kwargs):
super(MainWindow, self).__init__(*args, **kwargs)
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
self.ui.button_open_settings.clicked.connect
(self.open_settings)
def open_settings(self):
self.settings_window = settings.MainWindow_settings(self)
self.settings_window.toggle_submitter.connect(self.set_toggle_vis)
self.settings_window.show()
def set_toggle_vis(self, toggle):
self.ui.frame_toggle_list.setVisible(toggle)
settings window.py
class MainWindow_settings(QMainWindow):
toggle_submitter = pyqtSignal(int)
def __init__(self, *args, **kwargs):
super(MainWindow_settings, self).__init__(*args,**kwargs)
self.ui = settings_ui.Ui_Form()
self.ui.setupUi(self)
def change_toggle(self)
toggle_enabled = 1
self.toggle_submitter.emit(toggle_enabled)
This is the current code I am using:
class Opening(QDialog):
def __init__(self):
super(Opening, self).__init__()
loadUi("reminder2.ui", self)
self.startbutton.clicked.connect(self.gotomain)
def gotomain(self):
main = MainWindow()
widget.addWidget(main)
widget.setCurrentIndex(widget.currentIndex()+1)
class MainWindow(QDialog):
def __init__(self):
super(MainWindow, self).__init__()
loadUi("reminder.ui",self)
self.typebutton.clicked.connect(self.med)
self.searchbutton.clicked.connect(self.medd)
self.med2.hide()
self.med3.hide()
self.med4.hide()
self.med5.hide()
self.med6.hide()
self.med7.hide()
self.med8.hide()
self.addbutton.clicked.connect(self.clickAdd)
def med(self):
self.stackedWidget.setCurrentWidget(self.typemed)
def medd(self):
self.stackedWidget.setCurrentWidget(self.searchmed)
def clickAdd(self):
self.med2.show()
I'm trying to create a set of PySide classes that inherit QWidget, QMainWindow, and QDialog. Also, I would like to inherit another class to overrides a few functions, and also set the layout of the widget.
Example:
Mixin:
class Mixin(object):
def __init__(self, parent, arg):
self.arg = arg
self.parent = parent
# Setup the UI from QDesigner
ui = Ui_widget()
ui.setupUi(self.parent)
def setLayout(self, layout, title):
self.parent.setWindowTitle(title)
self.parent.setLayout(layout)
def doSomething(self):
# Do something awesome.
pass
Widget:
class Widget(Mixin, QtGui.QWidget):
def __init__(self, parent, arg):
super(Widget, self).__init__(parent=parent, arg=arg)
This won't work, but doing this through composition works
Widget (Composition):
class Widget(QtGui.QWidget):
def __init__(self, parent, arg):
super(Widget, self).__init__(parent=parent)
mixin = Mixin(parent=self, arg=arg)
self.setLayout = mixin.setLayout
self.doSomething = mixin.doSomething
I would like to try to have the widget inherit everything instead of having part of it done through composition. Thanks!
Keep class Widget(Mixin, QtGui.Widget):, but add a super call in Mixin.__init__. This should ensure the __init__ method of both Mixin and QWidget are called, and that the Mixin implementation of the setLayout method is found first in the MRO for Widget.
class Mixin(object):
def __init__(self, parent=None, arg=None):
super(Mixin, self).__init__(parent=parent) # This will call QWidget.__init__
self.arg = arg
self.parent = parent
# Setup the UI from QDesigner
ui = Ui_widget()
ui.setupUi(self.parent)
def setLayout(self, layout, title):
self.parent.setWindowTitle(title)
self.parent.setLayout(layout)
def doSomething(self):
# Do something awesome.
pass
class Widget(Mixin, QtGui.QWidget):
def __init__(self, parent, arg):
super(Widget, self).__init__(parent=parent, arg=arg) # Calls Mixin.__init__
How can I subclass the QPushbutton in Pyside but require an arg. In my example I need the arg to be a list of ints [0,0,0].
My goal is to make it so i can create MyButton like this:
# GOAL
MyButton([0,255,0])
When the arguement containing the list of values is passed in, it should set the value self._data. I'm not sure if i have this setup correctly, so any corrections are appreciated.
class MyButton(QtGui.QPushButton):
def __init__(self, *args, **kwargs):
super(MyButton, self).__init__(*args, **kwargs)
self._data = stuff
#property
def data(self):
return self._data
#data.setter
def data(self, value):
self._data = value
MyButton([0,255,0])
Updated: I noticed though when i pass that value into my Init it doesn't appear to trigger the setter for that property?? Why is that? If you test the code below, you'll see the color of the button isn't set when it's instantiated. How do i fix that?
import os
import sys
import json
from PySide import QtCore, QtGui
class QColorSwatch(QtGui.QPushButton):
colorClicked = QtCore.Signal(list)
colorChanged = QtCore.Signal(list)
def __init__(self, stuff, *args, **kwargs):
super(QColorSwatch, self).__init__(*args, **kwargs)
self._color = stuff
self.setMaximumWidth(22)
self.setMaximumHeight(22)
self.setAutoFillBackground(True)
self.pressed.connect(self.color_clicked)
#property
def color(self):
return self._color
#color.setter
def color(self, value):
self._color = value
pixmap = QtGui.QPixmap(self.size())
pixmap.fill(QtGui.QColor(value[0], value[1], value[2]))
self.setIcon(pixmap)
self.colorChanged.emit(value)
# swatch.setIconSize(pixmap.size() - QtCore.QSize(6,6))
def color_clicked(self):
self.colorClicked.emit(self.color)
class ExampleWindow(QtGui.QMainWindow):
def __init__(self, parent=None):
super(ExampleWindow, self).__init__(parent)
self.resize(300, 200)
self.ui_swatch = QColorSwatch([255,0,0])
# main layout
main_layout = QtGui.QVBoxLayout()
main_layout.setContentsMargins(5,5,5,5)
main_layout.setSpacing(5)
main_layout.addWidget(self.ui_swatch)
main_widget = QtGui.QWidget()
main_widget.setLayout(main_layout)
self.setCentralWidget(main_widget)
# Signals
self.ui_swatch.colorClicked.connect(self.color_clicked)
self.ui_swatch.colorChanged.connect(self.color_changed)
def color_clicked(self, col):
print 'CLICKED:', col
self.ui_swatch.color = [255,0,0]
def color_changed(self, col):
print 'CHANGED:', col
def main():
app = QtGui.QApplication(sys.argv)
ex = ExampleWindow()
ex.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
You have to put stuff as a parameter.
class MyButton(QtGui.QPushButton):
def __init__(self, stuff, *args, **kwargs):
super(MyButton, self).__init__(*args, **kwargs)
self._data = stuff
#property
def data(self):
return self._data
#data.setter
def data(self, value):
self._data = value
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
mainWin = MyButton([0,255,0])
print(mainWin.data)
mainWin.show()
sys.exit(app.exec_())
Update:
You have to use self.color to use the setter.
class QColorSwatch(QtGui.QPushButton):
colorClicked = QtCore.Signal(list)
colorChanged = QtCore.Signal(list)
def __init__(self, stuff, *args, **kwargs):
super(QColorSwatch, self).__init__(*args, **kwargs)
self._color = None
self.color = stuff
self.setMaximumWidth(22)
self.setMaximumHeight(22)
self.setAutoFillBackground(True)
self.pressed.connect(self.color_clicked)
#property
def color(self):
return self._color
#color.setter
def color(self, value):
self._color = value
pixmap = QtGui.QPixmap(self.size())
pixmap.fill(QtGui.QColor(value[0], value[1], value[2]))
self.setIcon(pixmap)
self.colorChanged.emit(value)
# swatch.setIconSize(pixmap.size() - QtCore.QSize(6,6))
def color_clicked(self):
self.colorClicked.emit(self.color)
The issue that I'm facing is when I want to split the functionality of the menubar into multiple files (classes), each of them specific for handling options (File/Help/Edit and so on).
In the Main UI class I have:
class MyFrame(QMainWindow):
def __init__(self):
super().__init__()
self.menu_bar = self.menuBar()
# Create menu
self.add_menu()
def add_menu(self):
help_menu = MenuHelp(self)
def getMenuBar(self):
return self.menu_bar
In the MenuHelp (class):
class MenuHelp(QMenu):
def __init__(self, parrent_widget):
super(MenuHelp, self).__init__()
self.menu_variable = parrent_widget.getMenuBar().addMenu('Help')
about_action = self.menu_variable.addAction('About')
about_action.setStatusTip('About')
about_action.triggered.connect(self.handle_trigger)
def handle_trigger(self):
print('Im here')
The menubar is correctly shown, but handle_trigger method is never called, any ideas on what am I doing wrong?
You must pass a parent to your QMenu. You must change:
class MenuHelp(QMenu):
def __init__(self, parrent_widget):
super(MenuHelp, self).__init__()
to:
class MenuHelp(QMenu):
def __init__(self, parrent_widget):
super(MenuHelp, self).__init__(parrent_widget)