I've just came across QDockWidgets. And I am blown away with the flexibility these widgets offer. But it appears they do require a proper planning ahead.
I put a simple example here:
import sys
from PyQt4 import QtCore, QtGui
class GUI(QtGui.QMainWindow):
def __init__(self):
super(GUI, self).__init__()
mainWidget=QtGui.QWidget()
self.setCentralWidget(mainWidget)
mainLayout = QtGui.QVBoxLayout()
mainWidget.setLayout(mainLayout)
DockA = QtGui.QDockWidget('DockA')
DockB = QtGui.QDockWidget('DockB')
mainLayout.addWidget(DockA)
mainLayout.addWidget(DockB)
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
dialog = GUI()
dialog.show()
dialog.raise_()
sys.exit(app.exec_())
First I am subclassing QMainWindow. Then QWidget is created. Then assigning it as central via .setCentralWidget(). Next QVBoxLayout() is created and set to mainWidget.
Now creating DockA and DockB. Dialog shows up. But docks are not movable.
What I am doing wrong here?
From the official documentation:
QDockWidget provides the concept of dock widgets, also know as tool palettes or
utilitywindows. Dock windows are secondary windows placed in the
"dock widget area" around the central widget in a QMainWindow
Please refer to the detailed description here and an example here. It is in C++ but you can get an idea of how to do things.
You should use the addDockWidget method of QMainWindow to get fully functional movable dock windows.
Example:
from PySide import QtCore, QtGui
app = QtGui.QApplication([])
window = QtGui.QMainWindow()
window.setCentralWidget(QtGui.QLabel('MainWidget'))
window.addDockWidget(QtCore.Qt.LeftDockWidgetArea, QtGui.QDockWidget('DockA'), QtCore.Qt.Vertical)
window.addDockWidget(QtCore.Qt.LeftDockWidgetArea, QtGui.QDockWidget('DockB'), QtCore.Qt.Vertical)
window.show()
app.exec_()
Related
I'm now using PyQt5 in python to develop a GUI for my program. I have added some QAction to the toolbar, like start, pause and stop icon. However, I don't know how to add a QSlider to the toolbar in my mainwindow. I prefer to add the QSlider to the position which is marked by a red rectangle. Thanks!
QToolBar has the addWidget() method that allows you to add widgets:
from PyQt5 import QtCore, QtWidgets
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
toolbar = self.addToolBar("toolbar")
toolbar.addAction("start")
toolbar.addAction("pause")
toolbar.addAction("stop")
self.slider = QtWidgets.QSlider(QtCore.Qt.Horizontal)
toolbar.addWidget(self.slider)
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())
I'm using PyQt4 with python 2.7 on Windows7
I have a QWidget that I want to stay above the QMainWindow while clicking on the main. The idea is that the main will contain a series of 'edit' buttons that will open the edit widget, while the edit widget refreshes with info contained on the main. I don't particularly care if either is "always on top" as long as the widget stays in front of the main window.
There are a couple of questions that address this topic, but I'm not seeing an answer that works for my specific use case. One deals in widgets but provides an answer only for the app main window (widget stays above other environmental windows but falls behind the application main window when clicking on the main), and the other addresses Qt generally but not a pythonic example:
PyQt: Always on top
How keep a QWidget always on top?
Here is the code I have so far:
from PyQt4 import QtCore, QtGui
class Ui_MainWindow(QtGui.QMainWindow):
def __init__(self):
QtGui.QMainWindow.__init__(self, None, QtCore.Qt.WindowStaysOnTopHint)
self.setWindowTitle("MainWindow")
self.resize(400, 300)
class Ui_Widget(QtGui.QWidget):
def __init__(self):
QtGui.QWidget.__init__(self, None, QtCore.Qt.WindowStaysOnTopHint)
self.setWindowTitle("Widget")
self.resize(400, 300)
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
MainWindow = Ui_MainWindow()
MainWindow.show()
Widget = Ui_Widget()
Widget.show()
sys.exit(app.exec_())
If you want Ui_Widget to always be on top of Ui_MainWindow, Ui_Widget must be a child of Ui_MainWindow and the flag Qt::Dialog must be activated as shown below:
from PyQt4 import QtCore, QtGui
class Ui_MainWindow(QtGui.QMainWindow):
def __init__(self):
QtGui.QMainWindow.__init__(self)
self.setWindowTitle("MainWindow")
self.resize(400, 300)
class Ui_Widget(QtGui.QWidget):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.setWindowFlags(self.windowFlags() | QtCore.Qt.Dialog)
self.setWindowTitle("Widget")
self.resize(400, 300)
self.move(200, 150)
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
MainWindow = Ui_MainWindow()
MainWindow.show()
Widget = Ui_Widget(MainWindow)
Widget.show()
sys.exit(app.exec_())
I'm just starting with pyqtgraph. I have a graphicsView widget that I promoted with QT designer per the documentation. I would like to try a plot to see if it works. When I tried pg.plot(x,y) the program created a plot in a separate window rather than in the graphicsView widget. I'm using Windows 10, PyQt4, and Python 2.7. What am I doing wrong?
from PyQt4 import QtGui
from PyQt4 import QtCore
import ui_test #Gui File
import sys
import pyqtgraph as pg
class Gui(QtGui.QMainWindow, ui_test.Ui_MainWindow):
def __init__(self):
super(self.__class__, self).__init__()
self.setupUi(self) # This is defined in ui_pumptest.py file automatically
self.plot()
def plot(self):
vb = pg.ViewBox()
self.graphicsView.setCentralItem(vb)
def main():
app = QtGui.QApplication(sys.argv) # A new instance of QApplication
form = Gui() # We set the form to be our ExampleApp (design)
form.show() # Show the form
app.exec_() # and execute the. app
if __name__ == '__main__': # if we're running file directly and not importing it
main() # run the main function
Can you share the ui_pumptest.py file source? Otherwise it's hard to tell what your intentions are. If not, at least detail what construct you used to place in the QGraphicsView promotion process in QtDesigner (assuming you followed http://www.pyqtgraph.org/documentation/how_to_use.html#embedding-widgets-inside-pyqt-applications).
pg.plot creates it's own plotwindow->plotwidget structure, so that's why you're getting a separate window if calling that. The item you call plot on should be the container object name that was promoted in your Qt Ui file.
A dialog created with:
class GUI(QtGui.QMainWindow):
def __init__(self):
super(GUI, self).__init__()
global dialog
dialog = QtGui.QDialog()
myGui = GUI()
is missing a minimize window button (OSX). It is there in Windows. Do I have to set some flag to display this missing controller? Please advise, Thanks in advance!
EDITED LATER:
I didn't try to solve a no-minimize-button issue with QtGui.QDialog(). But it appears I partically aware how to get that missing button using QtGui.QMainWindow.
Here is the simplest code illustrating a basic syntax:
from PyQt4 import QtCore, QtGui
app = QtGui.QApplication(sys.argv)
class MainWindow(QtGui.QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
myQWidget = QtGui.QWidget()
myBoxLayout = QtGui.QVBoxLayout()
myLineEdit = QtGui.QLineEdit("myLineEdit")
myBoxLayout.addWidget(myLineEdit)
myQWidget.setLayout(myBoxLayout)
self.setCentralWidget(myQWidget)
window = MainWindow()
window.show()
window.resize(480,320)
sys.exit(app.exec_())
A 'key' 'concept' behind QtGui.QMainWindow is that first we declare QWidget()
myQWidget = QtGui.QWidget()
to which we assign a 'main' layout:
myQWidget.setLayout(myBoxLayout)
Last step not to forget is to assign this QWidget() to dialog itself using:
self.setCentralWidget(myQWidget)
where 'self' is an instanced subclass of QtGui.QMainWindow.
I can't test this myself, but you could try setting these window flags:
dialog.setWindowFlags(dialog.windowFlags() |
QtCore.Qt.WindowMinimizeButtonHint |
QtCore.Qt.WindowSystemMenuHint)
(The WindowSystemMenuHint flag may not be necessary).
QtGui.QDialog does not offer a minimize button on any platform, but QtGui.QMainWindow does offer on each platform (Windows, Linux and OSX). You are creating a QDialog object and at the same time an object of GUI which is subclass of QMainWindow. If you write myGui.show() the window will offer you all three buttons (minimize, maximize/restore and close). But in case of dialog.show(), you will not have two of them (minimize and maximize/restore). It's Qt's limitation.
I just started dwelling into the realm of Qt (coming from PyGTK) and I'm using PySide. So I found this great example on another answer here on stack exchange.
import sys
from PySide.QtCore import *
from PySide.QtGui import *
from PySide.QtWebKit import *
app = QApplication(sys.argv)
web = QWebView()
web.settings().setAttribute(
QWebSettings.WebAttribute.DeveloperExtrasEnabled, True)
# or globally:
# QWebSettings.globalSettings().setAttribute(
# QWebSettings.WebAttribute.DeveloperExtrasEnabled, True)
web.load(QUrl("http://www.google.com"))
web.show()
inspect = QWebInspector()
inspect.setPage(web.page())
inspect.show()
sys.exit(app.exec_())
My question is as follows, how do I make the inspector show up in the same window instead of a new one? I understand I need to add the QWebInspector to another widget inside the main window (a vbox for example), what I want to know is how to connect that event to the signal the context menu "Inspect" triggers. In PyGTK I would need to use .connect() but I can't find the right SIGNAL for this specific action.
Thanks for your time guys/gals
It shouldn't be necessary to do anything special for the context menu to work. Just add an inspector widget to your layout, and hide() it to start with. The default context menu action can then show() the inspector as needed.
A slightly trickier issue is how to hide the inspector again once it's shown, as there doesn't seem to be a corresponding context menu item for that.
The demo script below simply creates a keyboard shortcut to hide/show the inspector:
from PySide import QtGui, QtCore, QtWebKit
class Window(QtGui.QWidget):
def __init__(self):
QtGui.QWidget.__init__(self)
self.view = QtWebKit.QWebView(self)
self.view.settings().setAttribute(
QtWebKit.QWebSettings.WebAttribute.DeveloperExtrasEnabled, True)
self.inspector = QtWebKit.QWebInspector(self)
self.inspector.setPage(self.view.page())
self.inspector.hide()
self.splitter = QtGui.QSplitter(self)
self.splitter.addWidget(self.view)
self.splitter.addWidget(self.inspector)
layout = QtGui.QVBoxLayout(self)
layout.addWidget(self.splitter)
QtGui.QShortcut(QtGui.QKeySequence('F7'), self,
self.handleShowInspector)
def handleShowInspector(self):
self.inspector.setShown(self.inspector.isHidden())
if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
window = Window()
window.view.load(QtCore.QUrl('http://www.google.com'))
window.show()
sys.exit(app.exec_())