Clicking QLabel should open a default web browser with URL link specified. It is not happening yet. Why?
A second question. Would it be possible to override the default blue color of the Label's font with something else?
class Widget(QtGui.QWidget):
def __init__(self, *args):
QtGui.QWidget.__init__(self, *args)
vLayout=QtGui.QVBoxLayout(self)
self.setLayout(vLayout)
urlLink="'Click this link to go to Google'"
label=QtGui.QLabel(self)
label.setText(urlLink)
vLayout.addWidget(label)
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
w = Widget()
w.show()
sys.exit(app.exec_())
The styling of the label's contents can be modified using the standard html syntax.
To automatically open external links:
label.setOpenExternalLinks(True)
In Qt Designer,
Ensure the label object containing the link is selected,
Locate the openExternalLinks property within the QLabel Group in the Property Editor (you can type open into the Property Editor filter field),
Set property openExternalLinks to True (checked). [This property is set to False by default.]
Related
I have a QTextBrowser() object:
self.PAddressLink = QTextBrowser()
I need to click on a link placed on this QTextBrowser, and it should open a new dialog box.
self.PAddressLink.setHtml("<html><body><a href=#>+Add Permanent Address</a></body></html>")
I can open the new window with the below code anyhow:
self.PAddressLink.anchorClicked.connect(self.AddPAddress) #self.AddPAddress is the method of displaying a dialog box.
But I need to know if I can place the self.AddPAddress in the href and avoid using the below extra statement:
self.PAddressLink.anchorClicked.connect(self.AddPAddress) #self.AddPAddress
Assuming all the methods are defined on the same object (e.g. self), you could set the method names in the href attribute:
self.PAddressLink.setHtml('...')
self.PAddressLink.anchorClicked.connect(self.handleLink)
and then use getattr to call the method:
def handleLink(self, url):
if url.scheme():
# handle normal urls here if necessary...
else:
getattr(self, url.toString())()
Here's a complete demo using both QLabel and QTextBrowser:
from PyQt5 import QtCore, QtGui, QtWidgets
html = """
<p>Url Link</p>
<p>Method Link</p>
"""
class Window(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.label = QtWidgets.QLabel(html)
self.browser = QtWidgets.QTextBrowser()
self.browser.setOpenLinks(False)
self.browser.setHtml(html)
layout = QtWidgets.QVBoxLayout(self)
layout.addWidget(self.browser)
layout.addWidget(self.label)
self.label.linkActivated.connect(self.handleLink)
self.browser.anchorClicked.connect(self.handleLink)
def handleLink(self, url):
url = QtCore.QUrl(url)
if url.scheme():
# handle real urls
QtGui.QDesktopServices.openUrl(url)
else:
# handle methods
getattr(self, url.toString())()
def myMethod(self):
QtWidgets.QMessageBox.information(self, 'Test', 'Hello World!')
if __name__ == '__main__':
app = QtWidgets.QApplication(['Test'])
window = Window()
window.setGeometry(600, 100, 300, 200)
window.show()
app.exec()
Most likely not. Atleast not any easy way. You'd be just reimplementing the signals and slots system most likely.
Just as with buttons, you have to connect the click signal to a slot. That's how it is designed to work.
In Qt Designer, I defined a couple of icons in the resource browser and I attached them to buttons and actions. The Designer preview shows the icons. Icons are stored in icons.qrc file.
But when I load the UI file :
class MyQtApp():
def __init__(self):
super().__init__()
self.ui = QUiLoader().load("ui/main.ui")
self.ui.show()
if __name__ == '__main__':
app = QtWidgets.QApplication([])
my_app = MyQtApp()
app.exec_()
the icons are lost. They don't appear on the buttons.
I don't mind compiling the icons.qrc using :
pyside2-rcc.exe icons.qrc -o icons_rc.py
but how can I link the icons_rc.py to my code if I use QUiLoader().load() ?
PS: Of course, when I use both the resource and the ui compiler (pyside2-uic.exe and pyside2-rcc.exe), I don't have this issue but I prefer using QUiLoader().load() if possible.
The only thing you have to do is to import the icons_rc.py in your main file.
Just add the statement
import icons_rc.py
In the beginning of you file and that's it. This works for me.
I'm quite new to PyQt and QtDesigner so probably it's easy what I'm tring to do but I couldn't find a working example anywhere.
I've created a GUI in QtDesigner with a tabWidget and multiple tabs (which are QWidgets) named tab,tab_2 etc.
Now I'm trying to add a pushbutton for example to the first tab (called tab). My previous try created the button in a new window..
What is the correct way to do this?
import sys
from PyQt5 import QtWidgets,QtCore, QtGui,uic
from PyQt5.Qt import QPushButton
class Main(QtWidgets.QMainWindow):
def __init__(self):
QtWidgets.QMainWindow.__init__(self)
self.ui = uic.loadUi('example.ui',self)
self.ui.tab.btn1=QtWidgets.QPushButton('buttonn')
self.ui.tab.btn1.show()
if __name__ == '__main__':
from PyQt5.QtWidgets import QApplication
app = QApplication(sys.argv)
window=Main()
window.show()
sys.exit(app.exec_())
The normal way to use QTabWidget is to do the following: Create a
QTabWidget. Create a QWidget for each of the pages in the tab dialog,
but do not specify parent widgets for them. Insert child widgets into
the page widget, using layouts to position them as normal. Call
addTab() or insertTab() to put the page widgets into the tab widget,
giving each tab a suitable label with an optional keyboard shortcut.
Try this:
class Main(QtWidgets.QMainWindow):
def __init__(self):
QtWidgets.QMainWindow.__init__(self)
self.ui = uic.loadUi('example.ui',self)
btn1=QtWidgets.QPushButton('buttonn')
self.ui.tabwidget.addTab(btn1, 'Tab name')
If you have the tabs already created, just create the button as a child of the widget inside the tab:
btn1=QtWidgets.QPushButton('buttonn', self.ui.tab)
I have a very basic QMainWindow application that contains a menubar and a statusbar. When I hover over the menu the status message disappears. More precisely, the status message is cleared. I have no idea what is causing this behavior but it's resulting in a very difficult workaround for what I hoped to be trivial behavior.
This is problematic for the following reason:
I can make the message permanent by adding a QLabel widget to the QStatusBar, but then I get the awkward border. I don't want the border. The only way I know how to remove the border is via QStatusBar.setStyleSheet(). I am using a palette for my color scheme as opposed to a stylesheet so modifying the stylesheet messes up other colors. I also can't restore the original statusBar QLabel color when I make a modification via the stylesheet. I'm not the best at using stylesheets.
Is there a way to prevent the menu interaction from clearing the status message? If not, is there a way to remove the border from the StatusBar when adding a QLabel widget while preserving my palette (maybe not via stylesheets)?
#!/usr/bin/env python
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
class win(QMainWindow):
def __init__(self,parent=None):
super(win,self).__init__(parent)
self.menubar = QMenuBar(self)
self.fileMenu = QMenu("File")
self.exitAction = QAction("Exit",self)
self.fileMenu.addAction(self.exitAction)
self.menubar.addMenu(self.fileMenu)
self.statusBar().showMessage("Hello")
self.connect(self.exitAction,SIGNAL("triggered()"), self.close)
if __name__ == "__main__":
app = QApplication(sys.argv)
GUI = win()
GUI.show()
app.exec_()
I got the same problem, and I found another way which is creating a new QLabel
self.myMessage = QtGui.QLabel()
self.myMessage.setText("Hello")
and add it as an widget to the status bar on the left
self.statusBar.addWidget(self.myMessage)
or on the right
self.statusBar.addPermanentWidget(self.myMessage)
Basically, each widget you hover over sets the status bar text to their statusTip property even when that property is an empty string.
For QMenu, the text is stored in the menuAction action status tip, so, you can have a text instead of just clearing the status bar with something like this:
self.fileMenu.menuAction().setStatusTip("File Menu is hovered")
To prevent anything to change the status bar, you can probably install an eventFilter on the status bar and filter out all QStatusTipEvent.
Just to update Lazywii's answer regarding using a QLabel. That code didn't work exactly as is so maybe there have been some changes since 2016 but what did work in 2020 on PyQt5 is:
self.myMessage = QtWidgets.QLabel()
self.myMessage.setText("My message not affected by tooltips from hovering")
self.statusbar.addWidget(self.myMessage)
One complete example
# Created by BaiJiFeiLong#gmail.com at 2022/2/15 22:27
from PySide2 import QtWidgets, QtCore, QtGui
class StatusTipFilter(QtCore.QObject):
def eventFilter(self, watched: QtCore.QObject, event: QtCore.QEvent) -> bool:
if isinstance(event, QtGui.QStatusTipEvent):
return True
return super().eventFilter(watched, event)
app = QtWidgets.QApplication()
window = QtWidgets.QMainWindow()
window.menuBar().addMenu("File")
window.statusBar().showMessage("Ready")
window.menuBar().installEventFilter(StatusTipFilter(window))
window.show()
app.exec_()
And to answer the portion about removing the border from the statusbar: self.statusbar().setStyleSheet("QStatusBar::item{ border: 0px solid black };") does the trick. It is important to setStyleSheet only on the statusbar object and not the entire application.
I need to implement a function in python which handles the "paste" when "ctrl+v" is pressed. I have a QTableView, i need to copy a field of the table and paste it to another field of the table. I have tried the following code, but the problem is that i don't know how to read the copied item (from the clipboard) in the tableView. (As it already copies the field and i can paste it anywhere else like a notepad). Here is part of the code which I have tried:
class Widget(QWidget):
def __init__(self,md,parent=None):
QWidget.__init__(self,parent)
# initially construct the visible table
self.tv=QTableView()
self.tv.show()
# set the shortcut ctrl+v for paste
QShortcut(QKeySequence('Ctrl+v'),self).activated.connect(self._handlePaste)
self.layout = QVBoxLayout(self)
self.layout.addWidget(self.tv)
# paste the value
def _handlePaste(self):
if self.tv.copiedItem.isEmpty():
return
stream = QDataStream(self.tv.copiedItem, QIODevice.ReadOnly)
self.tv.readItemFromStream(stream, self.pasteOffset)
You can obtain the clipboard form the QApplication instance of your app using QApplication.clipboard(), and from the QClipboard object returned you can get the text, image, mime data, etc. Here is an example:
import PyQt4.QtGui as gui
class Widget(gui.QWidget):
def __init__(self,parent=None):
gui.QWidget.__init__(self,parent)
# initially construct the visible table
self.tv=gui.QTableWidget()
self.tv.setRowCount(1)
self.tv.setColumnCount(1)
self.tv.show()
# set the shortcut ctrl+v for paste
gui.QShortcut(gui.QKeySequence('Ctrl+v'),self).activated.connect(self._handlePaste)
self.layout = gui.QVBoxLayout(self)
self.layout.addWidget(self.tv)
# paste the value
def _handlePaste(self):
clipboard_text = gui.QApplication.instance().clipboard().text()
item = gui.QTableWidgetItem()
item.setText(clipboard_text)
self.tv.setItem(0, 0, item)
print clipboard_text
app = gui.QApplication([])
w = Widget()
w.show()
app.exec_()
Note: I've used a QTableWidget cause I don't have a model to use with QTableView but you can adapt the example to your needs.