Consider the following toy example:
from PyQt5 import QtWidgets, QtGui
class MainWindow(QtWidgets.QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.w = QtWidgets.QWidget()
layout = QtWidgets.QVBoxLayout()
self.w.setLayout(layout)
self.setCentralWidget(self.w)
toyLabel = QtWidgets.QLabel("Hello!")
layout.addWidget(toyLabel)
font = QtGui.QFont("Times", 16, QtGui.QFont.Bold)
font.setStretch(150)
toyLabel.setFont(font)
if __name__ == '__main__':
app = QtWidgets.QApplication([])
window = MainWindow()
window.show()
app.exec_()
How can I expand the letters of toyLabel without distorting it?
When using setStretch() as above the result is a mess:
I have also tried to expand the letters using a font-stretch property in a stylesheet but this is not supported.
Apparently, this can be set directly in the font stylesheet property:
QLabel {
font: 12px Times Expanded;
}
Related
I'm having trouble with spacing widgets in a QVboxlayout. I have this code:
from PyQt5 import QtGui, QtWidgets, QtCore
from PyQt5.QtWidgets import QApplication, QMainWindow
import sys
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
win_w, win_h = 250, 1
self.setGeometry((1920 - win_w) // 2, (1080 - win_h) // 2, win_w, win_h)
self.setWindowTitle('Test')
self.setFont(QtGui.QFont('Times', 12))
self.central_widget()
def central_widget(self):
widget = QtWidgets.QWidget()
grid = QtWidgets.QGridLayout()
group_box1 = QtWidgets.QGroupBox('Group Box')
v1 = QtWidgets.QVBoxLayout()
text_edit1 = QtWidgets.QTextEdit()
v1.addWidget(QtWidgets.QPushButton('Button'))
v1.addWidget(text_edit1)
group_box1.setLayout(v1)
grid.addWidget(group_box1, 0, 0)
widget.setLayout(grid)
self.setCentralWidget(widget)
if __name__ == '__main__':
app = QApplication(sys.argv)
win = MainWindow()
win.show()
sys.exit(app.exec_())
Running this brings up this window:
Adding this line v1.setSpacing(100) changes it to this:
Is there any way to make it add the spacing horizontally? Like this:
Use the alignment keyword argument for addWidget():
v1.addWidget(QtWidgets.QPushButton('Button'), alignment=QtCore.Qt.AlignRight)
As already suggested, you should carefully read the documentation about layout managers, including all the listed QLayout subclasses and all their methods. You can do some experiments on your own with them also in Designer, so that you can better understand how they work by directly seeing the results.
I am creating an application where I have a main window whit a label and then a docked widget that is in another file. I want to change the main windows label from a button at the docked widget. I try to import the main window file but then I can not access to the label. And I also tried to call a function in the main windows that changes the label but then the label does not change.
Here is the code:
main_window.py:
import results_window
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.define_main_windows()
self.create_dock_widgets()
def define_main_windows(self):
# Define de Main window properties
self.setMinimumSize(QSize(300, 100))
self.setWindowTitle("Python SkyLibris")
self.setWindowIcon(QtGui.QIcon("skylibris_icon.png"))
self.setStyleSheet("QMainWindow {background: 'white';}")
self.top = 50
self.left = 0
self.width = 1300
self.height = 400
self.setGeometry(self.left, self.top, self.width, self.height)
self.result = QLabel("result:")
self.setCentralWidget(self.result)
def create_dock_widgets(self):
# Create dock widgets
self.results_window = results_window.results_window()
self.resultsWindowDock = QDockWidget("Results Viewer", self)
self.resultsWindowDock.setWidget(self.results_window )
self.resultsWindowDock.setFloating(False)
self.resultsWindowDock.setVisible(True)
self.addDockWidget(Qt.LeftDockWidgetArea, self.resultsWindowDock)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
app.setStyle('Fusion')
mainWin = MainWindow()
mainWin.show()
sys.exit(app.exec_())
results_window.py:
import main_window
class results_window(QWidget):
def __init__(self):
super(results_window, self).__init__()
print("init")
self.label = QLabel()
self.value = QLineEdit()
self.bt = QPushButton("Click")
self.bt.clicked.connect(self.clickMethod)
self.main_layout = QVBoxLayout()
self.main_layout.addWidget(self.label)
self.main_layout.addWidget(self.value)
self.main_layout.addWidget(self.bt)
self.setLayout(self.main_layout)
def clickMethod(self):
print(self.value.text())
text = self.value.text()
main_window.result.setText(text)
You are using the wrong tools, for example your code has a circular import that causes your application to close since it is equivalent to a while True.
In Qt, signals and slots are used to share data asynchronously, as well as contributing to the fact that there is no coupling between classes. In your case, Results_Window must have a signal that transmits that information to the MainWindow, this signal must be emit within clickMethod.
results_window.py
from PyQt5 import QtCore, QtWidgets
class Results_Window(QtWidgets.QWidget):
resultChanged = QtCore.pyqtSignal(str)
def __init__(self):
super(Results_Window, self).__init__()
print("init")
self.label = QtWidgets.QLabel()
self.value = QtWidgets.QLineEdit()
self.bt = QtWidgets.QPushButton("Click")
self.bt.clicked.connect(self.clickMethod)
main_layout = QtWidgets.QVBoxLayout(self)
main_layout.addWidget(self.label)
main_layout.addWidget(self.value)
main_layout.addWidget(self.bt)
#QtCore.pyqtSlot()
def clickMethod(self):
text = self.value.text()
self.resultChanged.emit(text)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
app.setStyle('Fusion')
w = Results_Window()
w.show()
sys.exit(app.exec_())
main_window.py
from PyQt5 import QtCore, QtGui, QtWidgets
import results_window
class MainWindow(QtWidgets.QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.define_main_windows()
self.create_dock_widgets()
def define_main_windows(self):
self.setMinimumSize(QtCore.QSize(300, 100))
self.setWindowTitle("Python SkyLibris")
self.setWindowIcon(QtGui.QIcon("skylibris_icon.png"))
self.setStyleSheet("QMainWindow {background: 'white';}")
top, left, width, height = 50, 0, 1300, 400
self.setGeometry(left, top, width, height)
self.result = QtWidgets.QLabel("result:")
self.setCentralWidget(self.result)
def create_dock_widgets(self):
self.results_window = results_window.Results_Window()
self.results_window.resultChanged.connect(self.result.setText)
self.resultsWindowDock = QtWidgets.QDockWidget("Results Viewer", self)
self.resultsWindowDock.setWidget(self.results_window )
self.resultsWindowDock.setFloating(False)
self.resultsWindowDock.setVisible(True)
self.addDockWidget(QtCore.Qt.LeftDockWidgetArea, self.resultsWindowDock)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
app.setStyle('Fusion')
mainWin = MainWindow()
mainWin.show()
sys.exit(app.exec_())
I had similar problem in PyQT5 where I was unable to access and set the local variables. After a lot of struggle I found writing to file and reading from file as the best solution. Simply write the desired output to file and access the same info from other file. Works great!
I am trying to put a QToolBar on a layout of a QWidget instead of QMainWindow. On QMainWindow and QWidget is working fine, but when i try to add it on a layout first, is not. Am I doing something wrong? Is it possible? Here is my code:
from PyQt4 import QtGui, QtCore
import sys
img = '../../Images/logo.png'
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
mainWin = QtGui.QMainWindow()
widget = QtGui.QWidget()
hLayout = QtGui.QHBoxLayout()
'''ToolBar On main Window '''
basicToolBar = mainWin.addToolBar('Basic')
basicToolBar.addAction(QtGui.QAction('Test', mainWin))
# basicToolBar.addAction(QtGui.QAction(QtGui.QIcon(img), 'Test', mainWin))
# mainWin.show()
'''ToolBar On Widget '''
# Case 1: Set widget as parent
# widgetToolBar = QtGui.QToolBar(widget)
# widgetToolBar.addAction(QtGui.QAction('Test', widget))
# widgetToolBar.addAction(QtGui.QAction(QtGui.QIcon(img), QtGui.QAction('Test', widget))
# Case 2: Set toolBat on a layout
widgetToolBar = QtGui.QToolBar()
widgetToolBar.addAction(QtGui.QAction('Test', None))
# widgetToolBar.addAction(QtGui.QAction(QtGui.QIcon(img), 'Test', None))
hLayout.addWidget(widgetToolBar)
widget.setLayout(hLayout)
widget.show()
# Run
sys.exit(app.exec_())
QToolBar can only be in a QMainWindow since the QMainWindow has a special layout.
So you can use a secondary QMainWindow without problems as I show below:
from PyQt4 import QtCore, QtGui
class MainWindow(QtGui.QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.tabwidget = QtGui.QTabWidget()
self.setCentralWidget(self.tabwidget)
for name in ("tab1", "tab2", "tab3"):
self.create_widgets(name)
def create_widgets(self, name):
w = QtGui.QMainWindow()
self.tabwidget.addTab(w, name)
basicToolBar = w.addToolBar('Basic')
basicToolBar.addAction('Test')
basicToolBar.addAction(QtGui.QIcon("home.png"), 'Test')
tab = QtGui.QTabWidget()
w.setCentralWidget(tab)
for i in range(10):
tab.addTab(QtGui.QWidget(), "tab-{}".format(i))
if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())
Hmmm have you read the description of QToolBar? http://doc.qt.io/qt-5/qtoolbar.html#details
I think it won't work like this if your Object isn't a child of QMainWindow. The documentation says:
When a QToolBar is not a child of a QMainWindow, it loses the ability to populate the extension pop up with widgets added to the toolbar using addWidget(). Please use widget actions created by inheriting QWidgetAction and implementing QWidgetAction::createWidget() instead.
Hi i have posted the code below through which i'm unable to display label in pyqt4. Any suggestions would be helpful .
from PyQt4 import QtGui
from PyQt4 import QtCore
import sys
class Entry_view(QtGui.QWidget):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.setGeometry(25, 25, 800, 480)
label = QtGui.QLabel()
label.setText("Welcome To Python GUI")
label.resize(100, 50)
# label.show(self)
self.show()
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
myapp = Entry_view()
sys.exit(app.exec_())
You did not keep a reference to the label, so it got garbage-collected before it could be shown. Try this instead:
self.label = QtGui.QLabel(self)
self.label.setText("Welcome To Python GUI")
self.label.resize(100, 50)
Why did you set the text but don't process the app using thus:
app.processEvents() # On the QApplication.
Or just do:
label = QtGui.QLabel(text="Welcome to Python GUI!")
Or:
label = QtGui.QLabel("Welcomme To Python GUI!")
Or another way is:
label.show() # No widgets on it.
code below is the solution ,
from PyQt4 import QtGui
from PyQt4 import QtCore
import sys
class Entry_view(QtGui.QWidget):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.setGeometry(25, 25, 800, 480)
label = QtGui.QLabel()
label.setText("Swipe The Card")
vbox = QtGui.QVBoxLayout()
label.setAlignment(Qt.AlignCenter)
vbox.addWidget(label)
vbox.addStretch()
self.setLayout(vbox)
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
myapp = Entry_view()
sys.exit(app.exec_())
I've tried using QComboBox's model() with no apparent success. I wonder if it would be possible to align a text at the center of QCombobox. Aside from text alignment it seems the item's font is not effected by changing its PointSize....
combo=QtGui.QComboBox()
comboModel=combo.model()
for name in ['one','two','three']:
item = QtGui.QStandardItem(name)
itemFont = item.font()
itemFont.setPointSize(8)
item.setFont(itemFont)
# item.setAlignment(QtCore.Qt.AlignCenter)
comboModel.appendRow(item)
You can use setAlignment method:
from PyQt4 import QtGui, QtCore
class Window(QtGui.QWidget):
def __init__(self):
QtGui.QWidget.__init__(self)
layout = QtGui.QVBoxLayout(self)
self.combo = QtGui.QComboBox()
self.combo.setEditable(True)
self.combo.lineEdit().setAlignment(QtCore.Qt.AlignCenter)
self.combo.addItems('One Two Three Four Five'.split())
layout.addWidget(self.combo)
if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
window = Window()
window.show()
sys.exit(app.exec_())