I create a ILPlotCube to render a 3D array in TwoDMode. I then add several lines in the scene.
It appears that when the mouse is located over a node, this node is highlighted in purple and its original color is removed.
Is this behaviour expected? If yes, how can I disable it?
For info, I'm running a notebook with dual graphics: Intel HD Graphics 4000 + GeForce GT 650M
All drawable nodes are marked by default when the mouse is over them. In order to disable this behavior, set the 'Markable' property to false:
var lines = new ILLines() {
Markable = false
};
scene.Camera.Add(lines);
Related
I have a bunch of checkable QToolbuttons, and I'd like the icons to be 'greyed out' in the unchecked state.
I can accomplish this by setting different files for the on/off states in the QIcon. like this:
tb = QToolButton()
tb.setCheckable(True)
ico = QIcon()
ico.addFile('color.jpg', QSize(16, 16), QIcon.Normal, QIcon.On)
ico.addFile('grey.jpg', QSize(16, 16), QIcon.Normal, QIcon.Off)
tb.setIcon(ico)
But since a QIcon can create a 'greyed out' version of itself that is used in disabled mode, I'd prefer to use the disabled mode icon over creating the grey version of all the icons myself. Is this possible?
You can get the grayed icon with QIcon.pixmap() and using the Disabled state, then set it again for the desired mode.
Since you want it for the Off state (the default) you have to first set the pixmap for the On state, get the grayed out pixmap and then set it with the other state:
original = QtGui.QPixmap('icon.png')
icon = QtGui.QIcon()
icon.addPixmap(original, QtGui.QIcon.Normal, QtGui.QIcon.On)
grayed = icon.pixmap(original.size(), QtGui.QIcon.Disabled, QtGui.QIcon.On)
icon.addPixmap(grayed, QtGui.QIcon.Normal, QtGui.QIcon.Off)
Note that while the common behavior of Qt is to gray out images, it is not guaranteed that it will happen on all platforms and styles.
Since we're talking about icons, we can assume that they are very small, so we can use a helper function to get a grayed out pixmap (while still respecting the alpha channel):
def getGrayed(src):
if isinstance(src, QtGui.QPixmap):
src = src.toImage()
dest = QtGui.QImage(src.size(), QtGui.QImage.Format_ARGB32)
widthRange = range(src.width())
for y in range(src.height()):
for x in widthRange:
pixel = src.pixelColor(x, y)
alpha = pixel.alpha()
if alpha < 255:
alpha //= 3
gray = QtGui.qGray(src.pixel(x, y))
pixel.setRgb(gray, gray, gray, alpha)
dest.setPixelColor(x, y, pixel)
return QtGui.QPixmap.fromImage(dest)
Then, do something similar to the above:
original = QtGui.QPixmap('iconalpha.png')
icon = QtGui.QIcon(getGrayed(original))
icon.addPixmap(original, QtGui.QIcon.Normal, QtGui.QIcon.On)
Obviously, this can be very demanding if there are many source icons and their size is somehow "big" (256x256 or more).
If you're worried about performance, the above getGrayed() function can be converted to a simple script that automatically creates grayed out icons.
Note that if that feature is required a lot of times in your code, you might consider creating your own QIconEngine subclass and create a custom static function to get the preferred icon (with modes already set) based on your needs.
So what I currently want to do is pretty much implement rofi in awesome.
The reason I want to do this and I don't just use rofi is because I want to learn how to 'auto-generate' widgets in awesome.
This will come in handy later when I'll implement things like network widgets that when clicked, shows you a panel, shows you the wifi hotspots available as rows, etc etc. So it's just for me to learn how awesome works better. But also, I want a program launcher.
And also, before someone suggests it, I already know that there's a built-in launcher in awesome, and I also know that there's this. This is not what I'm looking for. I want to have the same thing thing rofi and dmenu have: I want to have suggestions pop up when you press keys. and I want to be able to click on the suggestions, etc.
What I want is something like this: uhhhh
So what I'm having problems is this: how do I auto-generate the rows? I want to be able to specify in only one place how many rows I want, and have awesome do the rest.
I've looked through Elv's github and I found radical and even though what he made is a menu system, I thought that I could use some of his code to do what I want. But I can't for the love of god figure out how it works. No offense to him, but it's not all too well docummented, even for users, and for actually explaining how the code works there's no docummentation.
So My question is: How can I make this work? How would I go about making the widgets that act as the rows automatically?
TL;DR:
i want to write a program launcher like rofi in awesome
i want to be able to specify only in one place the number of rows
therefore, (((I think))) I need to automatically generate widgets as rows somehow, how can I do it?
EDIT:
What I want is to be able to create the rows of my launcher automatically. I know I can hardcode the rows myself, have each row have a different id and then I can write a function that on each keypress, will update each widget with the most relevant matches. So it would be something like (not tested at all):
local wibox = require("wibox")
local awful = require("awful")
local num_rows = 10
local row_height = 40
-- set the height of the background in accordance to how many rows there are,
-- and how high each row should be
local prompt_height = row_height * num_rows
local prompt_width = 300
-- make a widget in the middle of the screen
local background = wibox({
x = awful.screen.focused().geometry.width / 2 - prompt_width / 2,
y = awful.screen.focused().geometry.height / 2 - prompt_height / 2,
width = prompt_width,
height = prompt_height,
bg = "#111111",
visible = false,
ontop = false
})
local rofi_launcher = wibox.widget({
widget = background,
{
-- get a flexible layout so the searchbox and the suggestion boxes get
-- scaled to take up all the space of the background
layout = wibox.layout.flex.vertical,
{ -- the prompt you actually type in
-- set id here so we can adjust its ratio later, so the magnifying
-- glass will end up on the right, and the texbox will take up the left side
id = "searchbox_and_mangifying_glass",
layout = wibox.layout.ratio.horizontal,
{
-- set id so we can use it as a prompt later
id = "searchbox",
widget = wibox.widget.textbox,
},
{
widget = wibox.widget.imagebox,
icon = '~/path/to/magnifying_glass_icon.svg',
},
},
{ -- this is where I actually create the rows that will display suggestions
{ -- row number 1
-- make a background for the textbox to sit in, so you can change
-- background color later for the selected widget, etc etc.
widget = wibox.widget.background,
{
-- give it an id so we can change what's displayed in the
-- textbox when we press keys in the prompt
id = "suggestion_1",
widget = wibox.widget.textbox,
},
},
{ -- row number 2
-- background, again
widget = wibox.widget.background,
{
-- id and textbox again
id = "suggestion_2",
widget = wibox.widget.textbox,
},
},
-- and another 8 (according to the `num_rows` variable) of the same two
-- textboxes above. This is exactly my problem. How can I make these
-- textboxes automatically and still be able to interact with them to
-- display suggestions on the fly, as the user types keys into the prompt?
},
},
})
If this is not clear enough please do let me know what you don't understand and I will update my question.
Equally untested as your code, but this creates a tables of textboxes instead of using the declarative layout to create all these textboxes:
[SNIP; For shorter code I removed some stuff at the beginning]
local textboxes = {}
local widgets = {}
for i = 1, num_rows do
local tb = wibox.widget.textbox()
local bg = wibox.widget.background(tb)
bg:set_bg("#ff0000") -- The original code did not set a bg color, but that would make the bg widget useless...?
tb.id = "suggestion_" .. tostring(i) -- This is likely unnecessary, but the original code set these IDs, too
table.insert(textboxes, tb)
table.insert(widgets, bg)
end
local rofi_launcher = wibox.widget({
widget = background,
{
-- get a flexible layout so the searchbox and the suggestion boxes get
-- scaled to take up all the space of the background
layout = wibox.layout.flex.vertical,
{ -- the prompt you actually type in
[SNIP - I did not change anything here; I only removed this part to make the code shorter]
},
widgets
},
})
-- Now make the textboxes display something
textboxes[3].text = "I am the third row"
textboxes[5].text = "I am not"
So when trying to add a HoverTool to a plot, the MultiLine Hover works.
But the problem I am having is, that I have another highlighting Single Line, that I do not want the Hover to act on.
So I wanted to input just the multiline to the renderers keyword
p.add_tools(HoverTool(tooltips = [('Name: ', '#Name'),
('Value', '#Value')],
renderers = [multiline]
)
and I am getting the following error:
ValueError: expected an element of either Auto or List(Instance(Renderer)), got [MultiLine(id='4982e76f-7dda-4d78-b729-240c9a29bdef', ...)]
What am I missing?
Glyphs (such as MultiLine) are more like a description of what to draw. There is a seperate GlyphRenderer that takes glyphs and uses them to draw (it can actually have several versions of a glyph to use in different cases, e.g. for selecting and highlighting and decimating). The renderers arg of the hover tool expects the GlyphRenderer, not the glyph.
If you are using bokeh.plotting, then the glyph renderer is returned by the method on the figure:
r = plot.multi_line(...) # r is what to configure on the hover tool
If you are using the low level bokeh.models API then you must already be configuring a GlyphRenderer manually for your MultiLine. Pass that to the hover tool instead.
I'm running on Windows 10, but using Delphi 7 (yes, I know it's quite old).
I want to use the system icons in Windows and have gone about this by defining a TImageList called SystemIcons which I initialize as follows:
var
fileInfo: TSHFileInfo;
begin
SystemIcons.Handle := ShGetFileInfo('', 0, fileInfo, SizeOf(fileInfo),
SHGFI_ICON or SHGFI_SMALLICON or SHGFI_SYSICONINDEX);
...
I have SystemIcons properties set statically as a TImageList component with width and height set to 16.
Elsewhere, I wish to retrieve an icon from this image list given a valid shell object's image index. Because these are "small system icons", I expect them to be 16x16. The result of calling GetSystemMetrics(SM_CYSMICON) yields 16. Oddly, the dimensions depend upon whether I retrieve them as a bitmap or an icon.
...
var
icon: TIcon;
bm: TBitmap;
begin
...
icon := TIcon.Create;
SystemIcons.GetIcon(imgIndex, icon);
bm := TBitmap.Create;
SystemIcons.GetBitmap(imgIndex, bm);
The imgIndex is correct and the same in both cases. The image retrieved is the same in each case, as expected. The dimensions of the bitmap (bm.Width and bm.Height) are also as expected: 16x16. However, the dimensions of the icon (icon.Width and icon.Height) are not. They are 32x32.
When I paint the icon on a canvas it appears as 16x16. So it's only its Height and Width values that appear incorrect. Very odd.
Why are these different?
The images are likely actually 32x32 to begin with.
Internally, TImageList.GetIcon() simply retrieves an HICON for the chosen image directly from the underlying Win32 ImageList API, using ImageList_GetIcon(), and assigns that to the TIcon.Handle property.
TImageList.GetBitmap(), on the other hand, is a bit different. It sizes the TBitmap to the dimensions of the TImageList (16x16), and then stretch draws the chosen image onto the TBitmap.Canvas using TImageList.Draw(), which in turn uses ImageList_DrawEx().
How is possible to display a QMessageBox::warning with the triangular exclamation mark symbol like the one following?
I can't find any option in QMessageBox::warning, I only get the red circular symbol.
The triangular icon should be the default for the QMessageBox::warning dialog, while the red circular one is the default for the QMessageBox::critical dialog.
In my python code I use either
QMessageBox.warning(None,QString("..."),QString("...."))
or the more complex
msg = "..."
q = QMessageBox(QMessageBox.Warning, "...", QString(msg))
q.setStandardButtons(QMessageBox.Ok);
i = QIcon()
i.addPixmap(QPixmap("..."), QIcon.Normal)
q.setWindowIcon(i)
q.exec_()
And both of them works well.
Eventually can you show the code you use to show the dialog ?
You can use the QMessageBox.setIcon() function to configure which symbol you see when the dialog is displayed.
The predefined icon property types are listed here: https://doc.qt.io/qt-5/qmessagebox.html#severity-levels-and-the-icon-and-pixmap-properties
Here is my C++ example of a message box with the yellow triangle icon:
QMessageBox msgWarning;
msgWarning.setText("WARNING!\nRunning low on coffee.");
msgWarning.setIcon(QMessageBox::Warning);
msgWarning.setWindowTitle("Caution");
msgWarning.exec();
And here is my C++ example of a message box with the red circle icon:
QMessageBox msgError;
msgError.setText("CRITICAL ERROR!\nThe McRib is no longer available!");
msgError.setIcon(QMessageBox::Critical);
msgError.setWindowTitle("Danger");
msgError.exec();